java中模运算符_java – 模运算符和按位AND的性能比较

让我们尝试用JMH重现.

@Benchmark

@Measurement(timeUnit = TimeUnit.NANOSECONDS)

@BenchmarkMode(Mode.AverageTime)

public int first() throws IOException {

return i % 2;

}

@Benchmark

@Measurement(timeUnit = TimeUnit.NANOSECONDS)

@BenchmarkMode(Mode.AverageTime)

public int second() throws IOException {

return i & 0x1;

}

好的,它是可重复的.第一个比第二个稍慢.现在让我们弄清楚原因.用-prof perfnorm运行它:

Benchmark Mode Cnt Score Error Units

MyBenchmark.first avgt 50 2.674 ± 0.028 ns/op

MyBenchmark.first:CPI avgt 10 0.301 ± 0.002 #/op

MyBenchmark.first:L1-dcache-load-misses avgt 10 0.001 ± 0.001 #/op

MyBenchmark.first:L1-dcache-loads avgt 10 11.011 ± 0.146 #/op

MyBenchmark.first:L1-dcache-stores avgt 10 3.011 ± 0.034 #/op

MyBenchmark.first:L1-icache-load-misses avgt 10 ≈ 10⁻³ #/op

MyBenchmark.first:LLC-load-misses avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:LLC-loads avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:LLC-store-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.first:LLC-stores avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:branch-misses avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:branches avgt 10 4.006 ± 0.054 #/op

MyBenchmark.first:cycles avgt 10 9.322 ± 0.113 #/op

MyBenchmark.first:dTLB-load-misses avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:dTLB-loads avgt 10 10.939 ± 0.175 #/op

MyBenchmark.first:dTLB-store-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.first:dTLB-stores avgt 10 2.991 ± 0.045 #/op

MyBenchmark.first:iTLB-load-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.first:iTLB-loads avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.first:instructions avgt 10 30.991 ± 0.427 #/op

MyBenchmark.second avgt 50 2.263 ± 0.015 ns/op

MyBenchmark.second:CPI avgt 10 0.320 ± 0.001 #/op

MyBenchmark.second:L1-dcache-load-misses avgt 10 0.001 ± 0.001 #/op

MyBenchmark.second:L1-dcache-loads avgt 10 11.045 ± 0.152 #/op

MyBenchmark.second:L1-dcache-stores avgt 10 3.014 ± 0.032 #/op

MyBenchmark.second:L1-icache-load-misses avgt 10 ≈ 10⁻³ #/op

MyBenchmark.second:LLC-load-misses avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.second:LLC-loads avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.second:LLC-store-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.second:LLC-stores avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.second:branch-misses avgt 10 ≈ 10⁻⁴ #/op

MyBenchmark.second:branches avgt 10 4.014 ± 0.045 #/op

MyBenchmark.second:cycles avgt 10 8.024 ± 0.098 #/op

MyBenchmark.second:dTLB-load-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.second:dTLB-loads avgt 10 10.989 ± 0.161 #/op

MyBenchmark.second:dTLB-store-misses avgt 10 ≈ 10⁻⁶ #/op

MyBenchmark.second:dTLB-stores avgt 10 3.004 ± 0.042 #/op

MyBenchmark.second:iTLB-load-misses avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.second:iTLB-loads avgt 10 ≈ 10⁻⁵ #/op

MyBenchmark.second:instructions avgt 10 25.076 ± 0.296 #/op

注意周期和指令的差异.现在这很明显了.第一个确实关心标志,但第二个不关心(只是按位).要确保这是原因,请查看程序集片段:

第一:

0x00007f91111f8355: mov 0xc(%r10),%r11d ;*getfield i

0x00007f91111f8359: mov %r11d,%edx

0x00007f91111f835c: and $0x1,%edx

0x00007f91111f835f: mov %edx,%r10d

0x00007f6bd120a6e2: neg %r10d

0x00007f6bd120a6e5: test %r11d,%r11d

0x00007f6bd120a6e8: cmovl %r10d,%edx

第二:

0x00007ff36cbda580: mov $0x1,%edx

0x00007ff36cbda585: mov 0x40(%rsp),%r10

0x00007ff36cbda58a: and 0xc(%r10),%edx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值