我需要检查两个整数是否多次位于零的同一侧。我不在乎它是正面还是负面,只是它是同一面…而性能非常重要。
目前,我正在这样做:
if (int1 == 0 || int2 == 0) { // handle zero } else if ((int1 ^ int2) > 0) { // different side } else { // same side }
与更明显的情况相比,这(通过caliper测试)的速度提高了30%:
if ((int1 > 0 && int2 > 0) || (int1 < 0 && int2 < 0)) {
可以更快地完成吗?
如果有人想看看我使用的30%测试框架,它就在这里。我用卡尺0.5-rc1
注意: 所有这些解决方案基本上都检查第一位,对于零,该位与一个正数相同。因此,如果这适用于您的应用程序,则无需进行零检查。
基准清单:
((&&)||(&&))
(>>31) == (>>31)
(0x80000000)
==
^
(^)>>31 == 0
0% Scenario{vm=java, trial=0, benchmark=XOR} 1372.83 ns; ?=7.16 ns @ 3 trials 17% Scenario{vm=java, trial=0, benchmark=Ifs} 2397.32 ns; ?=16.81 ns @ 3 trials 33% Scenario{vm=java, trial=0, benchmark=Bits} 1311.75 ns; ?=3.04 ns @ 3 trials 50% Scenario{vm=java, trial=0, benchmark=XorShift} 1231.24 ns; ?=12.11 ns @ 5 trials 67% Scenario{vm=java, trial=0, benchmark=BitAndXor} 1446.60 ns; ?=2.28 ns @ 3 trials 83% Scenario{vm=java, trial=0, benchmark=BitAndEquals} 1492.37 ns; ?=14.62 ns @ 3 trials benchmark us linear runtime XOR 1.37 ================= Ifs 2.40 ============================== Bits 1.31 ================ XorShift 1.23 =============== BitAndXor 1.45 ================== BitAndEquals 1.49 ================== vm: java trial: 0
看起来@aaronman是赢家
(int1 ^ int2) >> 31 == 0 ? /*on same side*/ : /*different side*/ ; 这不一定正确处理0,我不确定在这种情况下您想做什么。 编辑:还想指出的是,如果这是在c而不是java中,则可以通过消除== 0布尔值在c中的工作方式而进一步优化,尽管
(int1 ^ int2) >> 31 == 0 ? /*on same side*/ : /*different side*/ ;
== 0