哪些因素影响java调用的性能?-java开发java经验技巧

哪些因素影响java调用的性能?-java开发java经验技巧

ID:30891338

大小:75.00 KB

页数:8页

时间:2019-01-04

哪些因素影响java调用的性能?-java开发java经验技巧_第1页
哪些因素影响java调用的性能?-java开发java经验技巧_第2页
哪些因素影响java调用的性能?-java开发java经验技巧_第3页
哪些因素影响java调用的性能?-java开发java经验技巧_第4页
哪些因素影响java调用的性能?-java开发java经验技巧_第5页
资源描述:

《哪些因素影响java调用的性能?-java开发java经验技巧》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、哪些因索影响Java调用的性能?■编程开发技术哪些因素影响Java调用的性能?木文由ImportNew-elviskang翻译自voxxed。欢迎加入翻译小组。转载请见文末要求。当时发生了什么?这得从一个小故事说起。我在一个Java核心库的邮件列表中提交了一个修改——重写了一些木是?final的方法。一石激起千层浪,这一改动引发了儿番讨论。而其中一个讨论的话题是:调用一个去除?final?标记的方法,将导致哪种程度的性能下降(performanceregression)。我不能确定这一改变是否会导致性能卜•降,但当我决定将此暂时搁置一边,试着寻找在这个讨论里是否冇人公布过任何相

2、关的完整基准测试(sanebenchmarks)时,结果空手而归。我不能肯定地说有关的基准测试是不存在的,或者说其他人没做过这方面的探讨。但我能肯定的是,在这里,连任何公开的代码评审都没有。唉,看來是时候写一个基准测试了。基准测试的方法论我决定选用一个和当不错的框架一一JMH來构建基准测试。如果你质疑它测试的准确性,那么建议你看下对这个框架作者(AlekseyShipdev)的访谈,或者阅读一下由NitsanWakart撰写的一篇彰显此框架风采的博文。现在,我想知道哪些因素影响了J3V3方法调用的性能。所以我决定以不同方式调用方法,并测算它们的性能开销。以单一变量为前捉来构造一

3、套基准测试,我便能逐个排除或确定,哪些因素或哪种组合会影响到方法调用的性能。内联让我们把这些方法调用点压扁方法调用的冇无,是一个影响程度既是最高又是最低的因素一一对于编译器来说,彻底优化方法调用所带来的开销并非不可能,有两种方法可以实现这样的需求:直接内联该方法木身和使用内联缓存(inlinecache)。千万别被引入的这些术语给吓倒一一它们都是通俗易懂的。现在我们假设有一个叫Foo的类,该类定义了一个叫bar的方法:classFoo{voidbar(){・・・}}我们以如下的方式调用bar方法:Foofoo=newFoo();foo.bar();这里有一个重要的知识点:实际调

4、用?bar?的位置,B

5、J?foo.bar(),称为调用点(callsite)o当我们说一个方法“被内联”,意指方法体被插入到了调用点的位置上,以代替方法调用。对于那些由许多短小的方法所构成的程序——我称之为被适当分解的程序一一内联可以有效地提升性能。这是因为结束以后可以发现,程序并没冇把所冇时间用在方法调用上,实际上程序并没冇工作!我们在JMH中可以借由?CompilerControl?注释控制一个方法是否被内联。关于内联缓存的概念,我稍后再来说明。层次结构深度与重写子类方法是因为父母让孩子慢下来了吗?如果我们移除一个方法的?final?关键字,便意味着我们能够重写它。所以这

6、是另一个在进行测试我们需要考虑的情况。我会选择在同一•层次结构小不同层次的子类里调用一些方法,并且在这些方法里有一些是会被不同层次的子类重写的。这样的测试能让我们确定或排除深的层次结构是否影响到重写所带來的性能开销。多态性动物世界:多态是如何表现的先前我提到调用点这一概念吋,我偷偷地冋避了i个相当重要的问题——因为在子类中可以重写一个非?final?方法,这使得调用点可以调用不同的方法。现假设我传入一个Foo的实例或一个重写了?bH?了类一一Betz的实例,编译器如何得知要调用哪一个?bar?方法呢?在默认情况下,方法将在Java屮被虚拟化(可重写)。对于任一调用点,编译器需要

7、在一个称为虚拟表(viable)的表中寻找与其对应的方法。这是个非常耗吋的过程,所以,能进行优化的编译器,总是会试图减少这种查询带來的开销。一种方法就是先询提到的内联,这的确是个良策,但前提是编译器能证明在给定的调用点上调用的方法唯一。而这样的调用点我们称为单态(monomorphic)调用点。不幸的是,进行这种分析需要耗费大量时间。所以在实际过程中,确定一个调用点是否单态是个不太可取的方法。对此,JIT编译器倾向于使用一利「替代方法:列出哪些类口J以在此调用点被调用,接着根据之前的N个相同的调用猜测此调用点是否是单态的。以假定某个调用点永远为单态,来进行投机性质的优化往往是可

8、取的行为。因为这样的优化往往都是正确的,但也因它无法确保永远正确,编译器需要在方法调用之前注入一个用于检查方法类型的防护机制。除了单态的调用点以外,还有两种调用点我们希望对其进行优化。-•种称为双态(bimorphic)调用点,在该点上有两个候选方法。对此你依然可以实现内联——借助防护代码,让其检测应调用哪一个方法,并引导程序跳转至内联在调用点的两个方法体屮真正对应的那一个。这样的方式还是比查看所右虚拟表的方式要快得多。但在某些情况下,我们得利用内联缓存來进行优化。内联缓存需要借助一张特定的

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。