当我和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-4770cpu@ 3.40GHz (系列: 0x6,型号: 0x3c,Intel: 0x3)
如果我将const设置为等于值,或者将值设置为0xffffffff,则不会发生任何更改。
发布于 2016-09-06 19:25:55
CPU的DIV和MOD指令非常昂贵,花费了50个或更多周期。当您使用变量除数时,使用这些指令是不可避免的。但是,当您使用常量除数时,可以将其编译成一系列更便宜的指令,如MUL、ADD和SHR。
黑客的喜悦,第10章介绍了解决这个问题的几种算法。
发布于 2016-09-06 19:11:40
小心这个答案--这只是直觉,
这是因为%运算符的性质
在testNModConst() 1230小于12345,所以模数只需要内部检查它们的大小,并意识到12345更大(一次操作)
在testConstModN() 12345大于1230时,模数必须做一系列运算(减法)才能计算出答案。
它取决于整数相对于常量的大小。
https://stackoverflow.com/questions/39356132
复制相似问题