java表达b非零_为什么(a * b!= 0)比Java中的(a!= 0 \u0026\u0026 b!= 0)快?

我在Java中编写一些代码,在某些时候,程序的流程是由两个int变量“a”和“b”是否非零决定的(注意:a和b从不为负,从不在整数溢出范围内)。

我可以评价它

if (a != 0 && b != 0) { /* Some code */ }

或者

if (a*b != 0) { /* Some code */ }

因为我期望这段代码每次运行数百万次,我想知道哪一个会更快。我做了一个实验,通过比较它们在一个巨大的随机生成的数组,我也很好奇,看看数组(数据分数= 0)的稀疏如何影响结果:

long time;

final int len = 50000000;

int arbitrary = 0;

int[][] nums = new int[2][len];

for (double fraction = 0 ; fraction <= 0.9 ; fraction += 0.0078125) {

for(int i = 0 ; i < 2 ; i++) {

for(int j = 0 ; j < len ; j++) {

double random = Math.random();

if(random < fraction) nums[i][j] = 0;

else nums[i][j] = (int) (random*15 + 1);

}

}

time = System.currentTimeMillis();

for(int i = 0 ; i < len ; i++) {

if( /*insert nums[0][i]*nums[1][i]!=0 or nums[0][i]!=0 && nums[1][i]!=0*/ ) arbitrary++;

}

System.out.println(System.currentTimeMillis() - time);

}

结果表明,如果你期望“a”或“b”等于0超过时间的〜3%,a * b!= 0比a!= 0& b!= 0:

c57305b7ffb1e41c055dd1034f353692.png

我很想知道为什么。有人可以露出一些光吗?是编译器还是在硬件级?

编辑:出于好奇…现在我学到了分支预测,我想知道模拟比较将显示为OR b是非零:

GpJoM.png

我们确实看到分支预测与预期相同的效果,有趣的是,该图沿着X轴有些翻转。

更新

1-我添加了!(a == 0 || b == 0)到分析,看看会发生什么。

2-我也包括了!= 0 ||在学习关于分支预测之后,出于好奇,b!= 0,(a b)!= 0和(a | b)!但是它们在逻辑上不等同于其他表达式,因为只有OR b需要非零才能返回true,因此它们不会被用于比较处理效率。

3-我还添加了我用于分析的实际基准,它只是迭代一个任意的int变量。

有些人建议包括!= 0& b!= 0,而不是!= 0&& b!= 0,预测它将更接近a * b!= 0,因为我们将删除分支预测效果。我不知道&可以使用布尔变量,我认为它只用于与整数的二进制操作。

注意:在我正在考虑这一切的情况下,int溢出不是一个问题,但这绝对是一个重要的考虑在一般情况下。

CPU:Intel Core i7-3610QM @ 2.3GHz

Java版本:1.8.0_45

Java(TM)SE运行时环境(build 1.8.0_45-b14)

Java HotSpot(TM)64位服务器VM(构建25.45-b02,混合模式)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值