加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java中的模数慢吗?

发布时间:2020-12-14 16:39:15 所属栏目:Java 来源:网络整理
导读:我一直在看JDK中ThreadLocal的实现,出于好奇,我发现这一点: /** * Increment i modulo len. */ private static int nextIndex(int i,int len) { return ((i + 1 len) ? i + 1 : 0); } 看起来很明显,这可以用简单的回报(i 1)%len实现,但我认为这些人知道他
我一直在看JDK中ThreadLocal的实现,出于好奇,我发现这一点:
/**
 * Increment i modulo len.
 */
 private static int nextIndex(int i,int len) {
     return ((i + 1 < len) ? i + 1 : 0);
 }

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

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

解决方法

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

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

让我们用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;
    }
}

结果:

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读