I have a loop with 2 counters: i and j. If they have the same value - iteration works much faster than if their values differ:
Benchmark                     Mode  Cnt       Score      Error  Units
FloatsArrayBenchmark.times   thrpt   20  341805.800 ± 1623.320  ops/s
FloatsArrayBenchmark.times2  thrpt   20  198764.909 ± 1608.387  ops/s
Java bytecode is identical, which means it's related to some lower level optimizations. Can someone explain why this is happening? Here's the benchmark:
import org.openjdk.jmh.annotations.*;
public class FloatsArrayBenchmark {
    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(new String[]{FloatsArrayBenchmark.class.getSimpleName()});
    }
    @Benchmark @Fork(value = 1, warmups = 0)
    public void times(Data data) {
        float[] result = new float[10000];;
        for (int i = 0, j=0; i < 9_999; i++,j++)
            result[j] = data.floats[i] * 10;
    }
    @Benchmark @Fork(value = 1, warmups = 0)
    public void times2(Data data) {
        float[] result = new float[10000];
        for (int i = 0,j=1; i < 9_999; i++,j++)
            result[j] = data.floats[i] * 10;
    }
    @State(Scope.Benchmark)
    public static class Data {
        private final float[] floats = new float[10000];
    }
}
Environment:
In the first (faster) version, i always (effectively) has the same value as j, so it:
public void times(Data data) {
    float[] result = new float[10000];;
    for (int i=0, j=0; i < 9_999; i++,j++)
        result[j] = data.floats[i] * 10;
}
can be re-written without j with identical effect:
public void times(Data data) {
    float[] result = new float[10000];;
    for (int i = 0; i < 9_999; i++)
        result[i] = data.floats[i] * 10;
}
It is likely that the compiler recognised thatj is redundant and eliminated it, resulting in half the number of ++ operations performed, which accounts for 1/3 of all aritmetic operations. This is consistent with the timings: the second version takes 70% longer per iteration. 70% is approxiately 50%, the result expected for a ratio of 3:2 operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With