漫画:奇怪,为什么在Java中 2*(i*i) 比 2*i*i 快?
既然我设计的两只小萌宠出场了,也该它们的粑粑出场了,有同学估计最近有点疑问,东哥为什么很长一段时间不输出原创文章了,难道不准备写下去了吗?我可是东哥的忠实读者呢!
东哥在这里告诉各位读者大大,东哥一定会写下去,除非真的有一天写不动了为止,东哥一直对技术痴迷,所以公众号还是会以技术文输出为主。
今天这篇文章,我们通过一个故事来深入聊聊 Java 编译背后的秘密。
东哥说这段代码来自于 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。但是如果你把 2ii 替换成 2*(i*i),执行时间大概在 0.50s ~ 0.55s。
对这段程序的两个版本分别执行 15 次,得到的结果如下。
我们可以看出 2*(ii) 比 2i*i 快 。
我们来分别查看它的字节码,这里东哥给我推荐了一款好用的 IDEA 插件,叫做 jclasslib bytecode viewer(你还不会用的话,可以去查看一下东哥一系列的 IDEA 文章《用 IDEA 跟踪 Java 源码的技巧 | 内部资料》,真心不错)。
2ii 的字节码如下。
2*(i*i) 的字节码如下。
我们可以发现除了字节码顺序不同外,没有其它异常,下一步该怎么办呢?
这里东哥给我推荐一款开源的工具,叫做 jitwatch,它可以查看查看分析HotSpot JIT compiler 生成的汇编代码,关于它的安装方法可以通过谷歌查阅。
查看是否安装成功?可以用下面的命令。
如何查看汇编代码?
运行时,添加参数 -XX:+PrintAssembly。
好了,那我们来分别看看它们的汇编代码,由于汇编代码很多,我这里就不贴出来了,各位同学可以去运行分析一下。
我这里就说一下结论,通过对比分析,我们会发现,2ii 进行了大量的堆栈操作,因此,需要保存大量的中间结果;而 2*(i*i) 只有少量的堆栈操作。
显而易见,2*(ii) 比 2i*i 快是由于 JIT 优化的结果。
说明:
本文资料来自于Stackoverflow、Github,漫画素材均为作者原创。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
PHP接收前端传值各种情况整理
PHP接收前端传值各种情况整理 服务端代码: header('Access-Control-Allow-Origin:*'); var_dump($_POST); exit; 情况 1) 传null $.post('http://xxxxx.xx/index.php', { "test": null }, function(data, status) { console.log(data); }); 结果: array(1) { ["test"]=> string(0) "" } 2) 传'' 代码: $.post('http://xxxxx.xx/index.php', { "test": '' }, function(data, status) { console.log(data); }); 结果: array(1) { ["test"]=> string(0) "" } 3) 传'[]' $.post('http://xxxxx.xx/index.php', { "test": '[]' }, function(data, status) { console.log...
- 下一篇
使用ELock实现高性能分布式锁(非轮询)
前言: 随着笔者的颜值不断提高,用户量的日益增长,传统的单机方案已经不能满足产品的需求。笔者在网上寻遍方案,发现均为人云亦云,一份以毫秒为精度的轮询分布式锁被转发转载上万次。然,该方案没法满足笔者性能要求。故此,笔者研发ELock插件,并发布本文章。 其实集群也好,分布式服务也好。当我们不能保证团队成员的整体素质,那么在某些业务上,分布式锁自然没法避免。 公认开发原则:能不使用分布式锁的,尽可能不使用 举个例子,一个商品交易,需要检查库存、检查余额、扣库存、扣款、变更订单状态。可能很多人觉得,在分布式环境下一定要分布式锁才能安全。 致此,笔者提供一种简单的方案: 订单处理{ if(订单状态!=待支付){ return 该订单已处理; } if(库存不足){ return 库存不足; } if(余额不足){ return 余额不足; } 事务管理(rollbackFor = Exception.class){ //修改订单状态 int changeLine = 执行语句( update 订单表 set status=已支付 whe...
相关文章
文章评论
共有0条评论来说两句吧...