Dic*_*ici 21 java performance modulo
ThreadLocal出于好奇,我一直在看JDK 中的实现,我发现了这个:
/**
* Increment i modulo len.
*/
private static int nextIndex(int i, int len) {
return ((i + 1 < len) ? i + 1 : 0);
}
Run Code Online (Sandbox Code Playgroud)
看起来很明显,这可以用一个简单的实现return (i + 1) % len,但我认为这些人知道他们的东西.知道为什么他们这样做了吗?
这段代码高度针对性能,使用自定义映射来保存线程局部映射,弱引用以帮助GC变得聪明等等,所以我想这是性能问题.Java模数是否缓慢?
apa*_*gin 25
% 在此示例中出于性能原因而避免使用.
div/ rem即使在CPU架构级别上操作也较慢; 不仅仅是在Java中.例如,idivHaswell上的最小指令延迟大约是10个周期,但只有1个周期add.
让我们使用JMH进行基准测试.
import org.openjdk.jmh.annotations.*;
@State(Scope.Benchmark)
public class Modulo {
@Param("16")
int len;
int i;
@Benchmark
public int baseline() {
return i;
}
@Benchmark
public int conditional() {
return i = (i + 1 < len) ? i + 1 : 0;
}
@Benchmark
public int mask() {
return i = (i + 1) & (len - 1);
}
@Benchmark
public int mod() {
return i = (i + 1) % len;
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
Benchmark (len) Mode Cnt Score Error Units
Modulo.baseline 16 avgt 10 2,951 ± 0,038 ns/op
Modulo.conditional 16 avgt 10 3,517 ± 0,051 ns/op
Modulo.mask 16 avgt 10 3,765 ± 0,016 ns/op
Modulo.mod 16 avgt 10 9,125 ± 0,023 ns/op
Run Code Online (Sandbox Code Playgroud)
如您所见,使用%比条件表达式慢约2.6倍.JIT无法在讨论的ThreadLocal代码中自动优化它,因为divisor(table.length)是可变的.
| 归档时间: |
|
| 查看次数: |
4307 次 |
| 最近记录: |