Translate-CS 板


LINE

原文网址:http://plumbr.eu/blog/how-expensive-is-a-method-call-in-java 译文网址:http://blog.dontcareabout.us/2013/03/java-method-call.html BBS 以 markdown 格式撰写 ______________________________________________________________________ 我们都遇到过这种场景: 看着设计不良的 code,听着写出这 code 的人辩称: 「你不能为了设计牺牲效能啊!」 而你就是无法说服那个人放弃那有 500 行的 method, 理由是一连串的呼叫有可能降低效能。 嗯... 在 1996 年的时候可能是真的吧? 但是後来 [JVM] 已经进化成为一个神奇的软体了。 要发现 JVM 有多神奇的方法之一是钻进 VM 了解更多最佳化的原理。 应用在 JVM 的技术是相当广泛的, 不过让我们看看其中一个技术「[inline method]」的细节。 用下面这个例子来解说最容易了: [JVM]: http://en.wikipedia.org/wiki/Java_virtual_machine [inline method]: http://en.wikipedia.org/wiki/Inline_function int sum(int a, int b, int c, int d) { return sum(sum(a, b),sum(c, d)); } int sum(int a, int b) { return a + b; } 执行这段程式码时,[JVM] 会判断是否可以将它替换成更有效的方式, 像是 `inlined`: int sum(int a, int b, int c, int d) { return a + b + c + d; } 请注意,这个最佳化是 VM 在做的,不是 compiler。 第一时间可能很难明白为甚麽会这样? 毕竟就上头的例子,你会疑惑: 为甚麽在 compile 阶段暂缓最佳化可以产生更有效率的 bytecocde 呢? 但是考虑其他没有那麽明显的案例,JVM 还是实作最佳化的首选: * [JVM] 除了有 static 的分析资料,也有执行期的资料。 在执行期,JVM 可以根据哪些 method 最常执行、 哪些载入动作是多余的、什麽时候用 copy propagation 是安全的...... 来做出更好的决策。 * [JVM] 可以得到底层架构的资讯, 像是 CPU 是几核心、heap size、设定档, 然後根据这些资讯来做出最佳选择。 让我们透过实际例子来理解这些假设。我弄了一个[小型测试程式], 用几种不同的方法加总 1024 个整数。 [小型测试程式]: https://bitbucket.org/Nikem/inline/src * 用一个 array 装 1024 个整数,然後用回圈取得加总结果。 这是一个相对来讲合理的实作方式。 实作的档案是 [InlineSummarizer.java]。 * 用递回的方式作 divide and conquer: 我把原来的 1024个 element 用递回的方法分成两半, 第一层递回得到两个长度为 512 的 array、 第二层递回得到四个长度为 256 的 array...... 以此类推。 为了计算 1024 个整数的总和,我制造出 1023 个额外的 method 呼叫。 实作的档案是 [RecursiveSummarizer.java] * 幼稚的 divide and conquer 方式: 虽然也是对 array 作分割,不过是透过额外的实际 method 来作切半的动作。 所以我呼叫 `sum512()`、`sum256()`、`sum128()`、......、sum2()` 直到我计算完所有的 element。 跟递回的方法一样,我制造出 1023 个额外的 method 呼叫。 实作的档案是 [IterativeSummarizer.java]。 [InlineSummarizer.java]: https://bitbucket.org/Nikem/inline/src/ 8e4e9eafdd2673896e8389dab7eb2bdd211ee7d5/src/eu/plumbr/demo/ inlining/InlineSummarizer.java?at=default [RecursiveSummarizer.java]: https://bitbucket.org/Nikem/inline/src/ 8e4e9eafdd2673896e8389dab7eb2bdd211ee7d5/src/eu/plumbr/demo/ inlining/RecursiveSummarizer.java?at=default [IterativeSummarizer.java]: https://bitbucket.org/Nikem/inline/src/ 8e4e9eafdd2673896e8389dab7eb2bdd211ee7d5/src/eu/plumbr/demo/ inlining/IterativeSummarizer.java?at=default 然後我用一个 [test class] 来执行这些程式。 第一个结果是没有最佳化过的程式码: [test class]: https://bitbucket.org/Nikem/inline/src/ 8e4e9eafdd2673896e8389dab7eb2bdd211ee7d5/src/eu/plumbr/demo/ inlining/Main.java?at=default ![first diagram](http://static.plumbr.eu/blog/wp-content/uploads// 2013/02/without-jit1.png) 我们可以看到 inline 是最快的,额外产生 1023 个 method 的方法慢了约 25000ns。 但是解读这张图时要记得:这是 JIT 还没有对程式码作彻底最佳化的结果。 在 2010 年间,我用我的 MB Pro 根据各个实作方式的不同, 做了 200 到 3000 次的测试。 更实际的结果如下:我把所有加总的实作方式执行超过 1000000 次, 然後排除 JIT 没有运作的部份,来展现它魔法: ![second diagram](http://static.plumbr.eu/blog/wp-content/uploads// 2013/02/with-jit.png) 我们可以看到即使 inline 还是表现比较好, 但是 iterative 的方式也展现了不错的速度。 但是 recursive 就有显着的差异,当 iterative 的方法仅有 20% 的 overhead, `RecursiveSummarizer` 花了 inline 方法所需时间的 3.4 倍。 显然我们必须知道:当你使用递回时,JVM 无法提供协助、 也不能使用 inline method call。 所以当你使用递回时,请注意这个限制。 撇开递回不谈,method 的 overhead 是几乎不存在的。 在 1023 个额外的 method 呼叫却只有差 205ns。 不要忘了测量单位是 ns(10^-9 秒)。 因此,感谢 JIT,我们可以放心地忽略大多数 method 呼叫所产生的 overhead。 当你的同事又再用「call stack 的 pop 没有效率」这种藉口 来掩饰他的肮脏程式码,让他先去上一下 [JIT 速成班]吧! 如果你想整备齐全以防堵同事的荒谬理由,请订阅我们的 [RSS] 或 [Twitter], 我们很高兴提供你更多案例研究。 [JIT 速成班]: http://plumbr.eu/blog/do-you-get-just-in-time-compilation [RSS]: http://plumbr.eu/blog/feed [Twitter]: https://twitter.com/JavaPlumbr -- 钱锺书: 说出来的话 http://www.psmonkey.org 比不上不说出来的话 Java 版 cookcomic 版 只影射着说不出来的话 and more...... --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.25.28.182







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP