package de.sirywell.benchmark;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;

@Warmup(iterations = 3, time = 3)
@Measurement(iterations = 3, time = 2)
@Fork(value = 1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class Modulo {

    private static final int SIZE = 1234;
    private int[] data;
    private long[] dataL;

    @Setup
    public void prepare() {
        RandomGenerator generator = RandomGeneratorFactory.getDefault().create(123);
        this.data = new int[SIZE];
        this.dataL = new long[SIZE];
        for (int i = 0; i < this.data.length; i++) {
            this.data[i] = generator.nextInt();
            this.dataL[i] = generator.nextLong();
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt01(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 1) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt02(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 2) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt03(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 3) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt04(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 4) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt05(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 5) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt06(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 6) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt07(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 7) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt08(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 8) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt09(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 9) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt10(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 10) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt11(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 11) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt12(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 12) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt13(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 13) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt14(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 14) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt15(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 15) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt16(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 16) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt17(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 17) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt18(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 18) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt19(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 19) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt20(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 20) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt21(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 21) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt22(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 22) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt23(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 23) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt24(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 24) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt25(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 25) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt26(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 26) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt27(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 27) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt28(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 28) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt29(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 29) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt30(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 30) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modInt31(Blackhole bh) {
        for (int datum : this.data) {
            bh.consume(datum % ((1 << 31) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong01(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 1) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong02(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 2) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong03(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 3) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong04(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 4) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong05(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 5) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong06(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 6) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong07(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 7) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong08(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 8) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong09(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 9) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong10(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 10) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong11(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 11) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong12(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 12) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong13(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 13) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong14(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 14) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong15(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 15) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong16(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 16) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong17(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 17) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong18(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 18) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong19(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 19) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong20(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 20) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong21(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 21) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong22(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 22) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong23(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 23) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong24(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 24) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong25(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 25) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong26(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 26) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong27(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 27) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong28(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 28) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong29(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 29) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong30(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 30) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong31(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 31) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong32(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 32) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong33(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 33) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong34(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 34) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong35(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 35) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong36(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 36) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong37(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 37) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong38(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 38) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong39(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 39) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong40(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 40) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong41(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 41) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong42(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 42) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong43(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 43) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong44(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 44) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong45(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 45) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong46(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 46) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong47(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 47) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong48(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 48) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong49(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 49) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong50(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 50) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong51(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 51) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong52(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 52) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong53(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 53) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong54(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 54) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong55(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 55) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong56(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 56) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong57(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 57) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong58(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 58) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong59(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 59) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong60(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 60) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong61(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 61) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong62(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 62) - 1));
        }
    }

    @Benchmark
    @OperationsPerInvocation(SIZE)
    public void modLong63(Blackhole bh) {
        for (long d : this.dataL) {
            bh.consume(d % ((1L << 63) - 1));
        }
    }
}
