Java中的模数慢吗?

前端之家收集整理的这篇文章主要介绍了Java中的模数慢吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直在看JDK中ThreadLocal的实现,出于好奇,我发现这一点:
  1. /**
  2. * Increment i modulo len.
  3. */
  4. private static int nextIndex(int i,int len) {
  5. return ((i + 1 < len) ? i + 1 : 0);
  6. }

看起来很明显,这可以用简单的回报(i 1)%len实现,但我认为这些人知道他们的东西.任何想法为什么他们这样做?

代码高度针对性能,具有用于持有线程本地映射的自定义映射,弱引用以帮助GC变得聪明等等,因此我猜这是一个性能问题. Java中的模数慢吗?

解决方法

在本例中出于性能原因避免了%.

即使在cpu架构级别,div / rem操作也较慢;不仅在Java中例如,Haswell上的idiv指令的最小延迟大约是10个周期,但是只有1个循环.

让我们用JMH进行基准测试.

  1. import org.openjdk.jmh.annotations.*;
  2.  
  3. @State(Scope.Benchmark)
  4. public class Modulo {
  5. @Param("16")
  6. int len;
  7.  
  8. int i;
  9.  
  10. @Benchmark
  11. public int baseline() {
  12. return i;
  13. }
  14.  
  15. @Benchmark
  16. public int conditional() {
  17. return i = (i + 1 < len) ? i + 1 : 0;
  18. }
  19.  
  20. @Benchmark
  21. public int mask() {
  22. return i = (i + 1) & (len - 1);
  23. }
  24.  
  25. @Benchmark
  26. public int mod() {
  27. return i = (i + 1) % len;
  28. }
  29. }

结果:

  1. Benchmark (len) Mode Cnt score Error Units
  2. Modulo.baseline 16 avgt 10 2,951 ± 0,038 ns/op
  3. Modulo.conditional 16 avgt 10 3,517 ± 0,051 ns/op
  4. Modulo.mask 16 avgt 10 3,765 ± 0,016 ns/op
  5. Modulo.mod 16 avgt 10 9,125 ± 0,023 ns/op

你可以看到,使用%比条件表达式慢〜2.6倍. JIT无法在讨论的ThreadLocal代码自动优化,因为除数(table.length)是可变的.

猜你在找的Java相关文章