为什么(n mod const)比(const mod n)更快?

时间:2016-09-06 19:03:59

标签: java x86-64 jmh

在玩jmh时,我遇到了一个奇怪的事情,我无法解释。

@BenchmarkMode(Mode.SingleShotTime)
@Measurement(iterations = 10, batchSize = Integer.MAX_VALUE)
@Warmup(iterations = 5, batchSize = Integer.MAX_VALUE)
@State(Scope.Thread)
public class Tests {
    private int value;

    @Setup(Level.Iteration)
    public void setUp() {
        value = 1230;
    }

    @Benchmark
    public boolean testConstModN() {
        return 12345 % value == 0;
    }

    @Benchmark
    public boolean testNModConst() {
       return value % 12345 == 0;
   }
}

结果低于

Benchmark                  Mode  Cnt   Score   Error  Units
Tests.testConstModN          ss   10  10.789 ± 0.305   s/op
Tests.testNModConst          ss   10   7.550 ± 0.067   s/op

我正在运行JDK 1.8.0_101,VM 25.101-b13,Intel(R)Core(TM)i7-4770 CPU @ 3.40GHz(系列:0x6,型号:0x3c,步进:0x3)

如果我将const设置为等于值,或者我将值设置为0xffffffff,则没有任何变化。

2 个答案:

答案 0 :(得分:7)

CPU的DIVMOD指令非常昂贵,耗资50个周期或更多。使用变量除数时,使用这些指令是不可避免的。但是,当您使用常量除数时,可以将其编译为一系列便宜得多的指令,例如MULADDSHR

Hacker's delight, chapter 10涵盖了几种解决此问题的算法。

答案 1 :(得分:1)

请注意这个答案,这只是直觉

这是因为%运算符的性质

testNModConst() 1230小于12345,因此模数只需要在内部检查它们的大小并意识到12345更大(一次操作)

testConstModN() 12345中大于1230,因此模数必须进行一系列操作(减法)来计算答案。

它取决于整数相对于常数

的大小