扫一扫下方二维码,关注本站官方公众号
获取永久解锁本站全部文章的验证码
还能不定期领现金红包

java中i+=2什么意思_漫画:奇怪,为什么在Java中 2*(i*i) 比 2*i*i 快?-Go语言中文社区

java中i+=2什么意思_漫画:奇怪,为什么在Java中 2*(i*i) 比 2*i*i 快?


f5d0e14232170337c7973dea65368e87.png
6771c79f6b88fa164fdaf1f349eb5f51.png

既然我设计的两只小萌宠出场了,也该它们的粑粑出场了,今天这篇文章,我们通过一个故事来深入聊聊 Java 编译背后的秘密。

2b53a8d832a90e0e572d93337eb7f241.png
8664e03dd09b699fbc799ab60b763fbe.png
308b5cf077856dcbe02d406a69d774a3.png
c1f4584c6c4b40120a3c877ff2c0d6f3.png
266e498e0793ead1953819e077c4cceb.png

东哥说这段代码来自于 Stackoverflow,真正去逛这个网站的同学还是很少),如下。

public static void main(String[] args) { long startTime = System.nanoTime(); int n = 0; for (int i = 0; i < 1000000000; i++) { n += 2 * i * i; } System.out.println((double) (System.nanoTime() - startTime) / 1000000000 + " s"); System.out.println("n = " + n);}

代码很简单吧,它的执行时间大概在 0.60s ~ 0.65s。但是如果你把 2*i*i 替换成 2*(i*i),执行时间大概在 0.50s ~ 0.55s。

对这段程序的两个版本分别执行 15 次,得到的结果如下。

8664e03dd09b699fbc799ab60b763fbe.png

我们可以看出 2*(i*i) 比 2*i*i 快 。

17deee6d60c2761974a68cc879031d1f.png

我们来分别查看它的字节码,这里东哥给我推荐了一款好用的 IDEA 插件,叫做 jclasslib bytecode viewer。

2*i*i 的字节码如下。

baba598230417b93c913df63835dc5f1.png

2*(i*i) 的字节码如下。

f5c2def233514d216f1d740844f96541.png

我们可以发现除了字节码顺序不同外,没有其它异常,下一步该怎么办呢?

8664e03dd09b699fbc799ab60b763fbe.png

这里东哥给我推荐一款开源的工具,叫做 jitwatch,它可以查看查看分析HotSpot JIT compiler 生成的汇编代码,关于它的安装方法可以通过谷歌查阅。

查看是否安装成功?可以用下面的命令。

cf35a3363262aaa9a4d8ac12bde21771.png

如何查看汇编代码?

运行时,添加参数 -XX:+PrintAssembly。

好了,那我们来分别看看它们的汇编代码,由于汇编代码很多,我这里就不贴出来了,各位同学可以去运行分析一下。

我这里就说一下结论,通过对比分析,我们会发现,2*i*i 进行了大量的堆栈操作,因此,需要保存大量的中间结果;而 2*(i*i) 只有少量的堆栈操作。

显而易见,2*(i*i) 比 2*i*i 快是由于 JIT 优化的结果。

68795ebe28226405730a070f8ed9c30b.png

-END-

纯洁的微笑

一个有故事的程序员

转发+关注+私信资料 获取更多Java干货

版权声明1:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39979080/article/details/113084197
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-12-12 00:52
  • 阅读 ( 471 )

0 条评论

请先 登录 后评论

官方社群