我需要多次检查两个整数是否在零的同一侧。我不在乎是积极的还是消极的,只是它是同一面。。。性能非常重要。
目前我正在做:
if (int1 == 0 || int2 == 0) {
// handle zero
} else if ((int1 ^ int2) > 0) {
// different side
} else {
// same side
}
这是一个30%的速度提高(测试卡钳)比更明显的:
if ((int1 > 0 && int2 > 0) || (int1 < 0 && int2 < 0)) {
能快点吗?
如果有人想看看我用的30%的测试框架,就在这里。我用的是卡尺0.5-rc1
注意:所有这些解决方案都检查第一位,基本上,对于零,它与正数相同。因此,如果这对您的应用程序有效,则不需要执行零检查。
基准清单:
xor:带有错误修复的原始答案
如果:很明显 ((&&)||(&&))
解决方案
比特:@hatchet的解决方案 (>>31) == (>>31)
比坦德克索:@greedyforda的解决方案 (0x80000000)
bitandequals:@greedyfoddha的解决方案修改为使用 ==
不是 ^
xorshift:@aaronman的解决方案 (^)>>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是赢家
6条答案
按热度按时间4uqofj5v1#
我会将它们位转换为无符号int,并对msb(最高有效位)进行异或运算—比任何比较(执行减法)或乘法都快得多
gg58donl2#
或
两者的思想是相同的-去掉所有符号位,然后比较是否相等。我不确定哪个更快,右移(>>)还是按位and(&)。
mjqavswn3#
另一个答案。。。
pwuypxnk4#
备选答案
比较符号位
比较符号位的替代方法
我刚核实过,但op的代码错了
int1 == int2
. 如果以下内容相同,则它们将始终打印不同的内容。b1payxdu5#
uqdfh47h6#
(int1 ^ int2) >> 31 == 0 ? /*on same side*/ : /*different side*/ ;
这不一定能正确处理0,我不确定在这种情况下您想做什么。edit:还想指出,如果这是用c而不是java实现的,那么可以通过去掉
== 0
因为布尔函数在c语言中的工作方式,所以情况会有所改变