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

Slo*_*mus 5 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;
   }
}
Run Code Online (Sandbox Code Playgroud)

结果如下

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
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*nik 7

CPU DIVMOD指令非常昂贵,耗时50个或更多.使用变量除数时,使用这些指令是不可避免的.然而,当你使用一个常数因子,这可以被编译成的便宜很多指令,如短序列MUL,ADDSHR.

黑客的喜悦,第10章介绍了解决这个问题的几种算法.

  • 这是:http://stackoverflow.com/questions/31372565/large-performance-gap-between-cpus-div-instruction-and-hotspots-jit-code/31378410#31378410 (2认同)
  • 我最喜欢的治疗方法是http://ridiculousfish.com/blog/posts/labor-of-division-episode-iii.html (2认同)