java 调用 js性能_太快了,太变态了:什么会影响Java中的方法调用性能?

java 调用 js性能

那么这是怎么回事?

让我们从一个简短的故事开始。 几周前,我提议对Java核心libs邮件列表进行更改 ,以覆盖当前final一些方法。 这刺激了一些讨论主题-其中之一是其中一个性能回归通过采取这是一个方法被引入的程度final免遭停止它final

我对是否会出现性能下降有一些想法,但是我将这些想法放在一边,试图询问是否有关于此主题的合理基准发布。 不幸的是我找不到任何东西。 这并不是说它们不存在,也没有其他人没有对此情况进行调查,但是我没有看到任何经过公共同行评审的代码。 所以–是时候写一些基准了。

标杆管理方法

因此,我决定使用功能强大的JMH框架来汇总这些基准。 如果您不相信框架会帮助您获得准确的基准测试结果,那么您应该看一下编写框架的Aleksey Shipilev的演讲 ,或者Nitsan Wakart的非常酷的博客文章,其中解释了它如何提供帮助。

就我而言,我想了解是什么影响了方法调用的性能。 我决定尝试各种不同的方法调用并衡量成本。 通过设置一组基准并一次仅更改一个因素,我们可以单独排除或了解不同因素或因素组合如何影响方法调用成本。

内联

flat_cat 让我们压缩这些方法的调用方法。

同时,最明显的影响因素是根本没有方法调用! 方法调用的实际成本有可能完全被编译器优化。 从广义上讲,有两种降低通话成本的方法。 一种是直接内联方法本身,另一种是使用内联缓存。 不用担心-这些是非常简单的概念,但是需要引入一些术语。 假设我们有一个名为Foo的类,它定义了一个名为bar的方法。

class Foo {void bar() { ... }
}

我们可以通过编写如下代码来调用bar方法:

Foo foo = new Foo();
foo.bar();

重要的是实际调用bar的位置– foo.bar() –称为callsite 。 当我们说某个方法被“内联”时,这意味着该方法的主体已被取而代之以进入方法,而不是方法调用。 对于由许多小方法组成的程序(我认为是一个适当分解的程序),内联可以显着提高速度。 这是因为该程序并没有花费大部分时间来调用方法,而是没有实际执行工作! 通过使用CompilerControl批注,我们可以控制JMH中是否内联方法。 稍后我们将回到内联缓存的概念。

层次深度和覆盖方法

IMG_3015 父母会放慢孩子的速度吗?

如果我们选择从方法中删除final关键字,则意味着我们将能够覆盖它。 因此,这是我们需要考虑的另一个因素。 因此,我采用了方法并在类层次结构的不同级别上调用了它们,并且还具有在层次结构的不同级别上被覆盖的方法。 这使我能够理解或消除深层次的层次结构如何影响成本。

多态性

多态性 动物:如何描述任何面向对象的概念。

当我较早提到呼叫站点的想法时,我偷偷地避免了一个相当重要的问题。 由于可以在子类中覆盖非final方法,因此我们的调用站点final可能会调用不同的方法。 因此,也许我传入了Foo或它的孩子Baz,它也实现了bar()。 您的编译器如何知道要调用的方法? 默认情况下,方法是Java中的虚拟(可重写)方法,它必须为每个调用在称为vtable的表中查找正确的方法。 这非常慢,因此优化编译器总是试图减少所涉及的查找成本。 我们前面提到的一种方法是内联,如果您的编译器可以证明只能在给定的调用站点上调用一种方法,则该方法非常有用。 这称为单态呼叫站点。

不幸的是,在很多情况下,证明呼叫站点是单态的分析最终可能是不切实际的。 JIT编译器倾向于采用另一种方法来分析在调用站点上调用的类型,并猜测如果该调用站点在前N个调用中是单态的,则基于它始终将是单态的假设,值得进行推测性优化。 这种推测性优化通常是正确的,但是由于并不总是正确的,因此编译器需要在方法调用之前注入防护以检查方法的类型。

不过,单态调用场并不是我们要优化的唯一情况。 许多调用站点被称为双态 –有两种可以调用的方法。 您仍然可以内联双态呼叫站点,方法是使用保护代码检查要调用的实现,然后跳转到该实现。 这仍然比完整方法调用便宜。 也可以使用内联缓存来优化这种情况。 内联缓存实际上并不将方法主体内联到调用站点中,但是它具有专门的跳转表,其作用类似于完整vtable查找上的缓存。 热点JIT编译器支持双态内联高速缓存,并声明具有3个或更多可能实现的任何呼叫站点都是megamorphic的

这将再分为3种调用情况供我们进行基准测试和研究:单态情况,双态情况和大态情况。

结果

让我们对结果进行分组,以便更轻松地从树木中查看木材。我介绍了原始数字以及围绕它们的一些分析。 具体的数字/成本并不是那么重要。 有趣的是,不同类型的方法调用之间的比率以及相关的错误率很低。 最快和最慢之间存在很大的差异– 6.26倍。 实际上,由于与测量空方法的时间相关的开销,差异可能更大。

这些基准的源代码可在github上找到 。 为了避免混淆,结果不会全部显示在一个块中。 最后,多态基准测试来自运行PolymorphicBenchmark ,而其他基准来自JavaFinalBenchmark

简单的呼叫网站

Benchmark                                                    Mode   Samples         Mean   Mean error    Units
c.i.j.JavaFinalBenchmark.finalInvoke                         avgt        25        2.606        0.007    ns/op
c.i.j.JavaFinalBenchmark.virtualInvoke                       avgt        25        2.598        0.008    ns/op
c.i.j.JavaFinalBenchmark.alwaysOverriddenMethod              avgt        25        2.609        0.006    ns/op

我们的第一组结果比较了虚拟方法, final方法和层次结构较深且被覆盖的方法的调用成本。 请注意,在所有这些情况下,我们都强制编译器不内联方法。 正如我们所看到的,时间之间的差异很小,而且我们的平均错误率表明它并不重要。 因此,我们可以得出结论,仅添加final关键字并不会大大提高方法调用的性能。 覆盖该方法似乎也没有太大区别。

内联简单的呼叫站点

Benchmark                                                    Mode   Samples         Mean   Mean error    Units
c.i.j.JavaFinalBenchmark.inlinableFinalInvoke                avgt        25        0.782        0.003    ns/op
c.i.j.JavaFinalBenchmark.inlinableVirtualInvoke              avgt        25        0.780        0.002    ns/op
c.i.j.JavaFinalBenchmark.inlinableAlwaysOverriddenMethod     avgt        25        1.393        0.060    ns/op

现在,我们采用了相同的三种情况,并删除了内联限制。 同样, final和virtual方法调用的结束时间彼此相似。 它们比非内联的情况快大约4倍,我将其归结为内联本身。 在此始终被覆盖的方法调用最终在两者之间。 我怀疑这是因为方法本身具有多个可能的子类实现,因此编译器需要插入类型保护。 上面在“ 多态性”中对此机制进行了详细说明。

类等级冲击

Benchmark                                                    Mode   Samples         Mean   Mean error    Units
c.i.j.JavaFinalBenchmark.parentMethod1                       avgt        25        2.600        0.008    ns/op
c.i.j.JavaFinalBenchmark.parentMethod2                       avgt        25        2.596        0.007    ns/op
c.i.j.JavaFinalBenchmark.parentMethod3                       avgt        25        2.598        0.006    ns/op
c.i.j.JavaFinalBenchmark.parentMethod4                       avgt        25        2.601        0.006    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentMethod1              avgt        25        1.373        0.006    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentMethod2              avgt        25        1.368        0.004    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentMethod3              avgt        25        1.371        0.004    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentMethod4              avgt        25        1.371        0.005    ns/op

哇–这是很多方法! 每个编号的方法调用(1-4)表示调用方法的类层次结构有多深。 所以parentMethod4意味着我们调用了在类的第4个父级上声明的方法。 如果看一下数字,则1和4之间的差异很小。因此,我们可以得出结论,层次深度没有区别。 可内联的案例都遵循相同的模式:层次深度没有区别。 我们的inlineable方法性能与inlinableAlwaysOverriddenMethod相当,但比inlinableVirtualInvoke慢。 我再次将其归结为所使用的类型防护。 JIT编译器可以对方法进行概要分析,以找出仅一个内联方法,但是无法证明这种方法永远存在。

类层次对

Benchmark                                                    Mode   Samples         Mean   Mean error    Units
c.i.j.JavaFinalBenchmark.parentFinalMethod1                  avgt        25        2.598        0.007    ns/op
c.i.j.JavaFinalBenchmark.parentFinalMethod2                  avgt        25        2.596        0.007    ns/op
c.i.j.JavaFinalBenchmark.parentFinalMethod3                  avgt        25        2.640        0.135    ns/op
c.i.j.JavaFinalBenchmark.parentFinalMethod4                  avgt        25        2.601        0.009    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentFinalMethod1         avgt        25        1.373        0.004    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentFinalMethod2         avgt        25        1.375        0.016    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentFinalMethod3         avgt        25        1.369        0.005    ns/op
c.i.j.JavaFinalBenchmark.inlinableParentFinalMethod4         avgt        25        1.371        0.003    ns/op

这遵循与上述相同的模式final关键字似乎没有什么区别。 我会认为这是可能在这里,从理论上说,对于inlinableParentFinalMethod4来加以证明inlineable没有型后卫,但它不会出现这种情况。

多态性

Monomorphic: 2.816 +- 0.056 ns/op
Bimorphic: 3.258 +- 0.195 ns/op
Megamorphic: 4.896 +- 0.017 ns/op
Inlinable Monomorphic: 1.555 +- 0.007 ns/op
Inlinable Bimorphic: 1.555 +- 0.004 ns/op
Inlinable Megamorphic: 4.278 +- 0.013 ns/op

最后,我们来谈谈多态调度的情况。 单态调用费用与我们上面的常规虚拟调用费用大致相同。 由于我们需要在较大的vtable上进行查找,因此随着双态和多态情况的显示,它们变得更慢。 一旦启用内联类型分析,我们的单态和双态调用站点就会降低“内联有警戒”方法调用的成本。 因此,与类层次结构的情况类似,只是速度较慢。 大形情况仍然很慢。 请记住,我们这里没有告诉热点防止内联,只是它没有为比双态更复杂的调用站点实现多态内联缓存。

我们学到了什么?

我认为值得一提的是,有很多人没有表现心理模型来说明花费时间不同的不同类型的方法调用,还有很多人知道他们花费的时间不同,但实际上并没有非常正确。 我知道我以前去过那里,做了各种各样的错误假设。 因此,我希望这项调查对人们有所帮助。 这是我很乐意支持的声明摘要。

  • 最快和最慢的方法调用类型之间有很大的不同。
  • 实际上,添加或删除final关键字并不会真正影响性能,但是,如果您随后重构层次结构,事情可能会开始放慢速度。
  • 更深的类层次结构对呼叫性能没有真正的影响。
  • 单态调用比双态调用更快。
  • 双态调用比大形调用快。
  • 在可概要分析但不能证明的情况下,我们看到的类型防护在单态调用站点上确实比在可证明的单态调用站点上放慢了很多速度。

我会说类型保护程序的成本是我个人的“大启示”。 这是我鲜为人知的话题,经常被认为是无关紧要的。

注意事项和进一步工作

当然,这不是主题领域的最终决定!

  • 该博客仅关注与方法调用性能有关的类型相关因素。 我没有提到的一个因素是由于主体大小或调用堆栈深度而导致的围绕方法内联的启发式方法。 如果您的方法太大,则根本不会内联,您仍然要为方法调用的费用支付费用。 编写小的,易于阅读的方法的另一个原因。
  • 我没有研究过接口调用如何影响这些情况。 如果您发现这很有趣,那么可以在Mechanical Sympathy博客上进行有关调用接口性能的调查。
  • 我们在这里完全忽略的一个因素是方法内联对其他编译器优化的影响。 当编译器执行仅考虑一种方法的优化(过程内优化)时,他们实际上希望获得尽可能多的信息,以便有效地进行优化。 内联的局限性可以大大缩小其他优化必须使用的范围。
  • 将说明直接附加到汇编级别,以深入了解该问题。

也许这些是将来博客文章的主题。

翻译自: https://www.javacodegeeks.com/2014/05/too-fast-too-megamorphic-what-influences-method-call-performance-in-java.html

java 调用 js性能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware虚拟机扩展Ubuntu系统磁盘空间

转载:https://www.cnblogs.com/dongry/p/10620894.html 1 首先给虚拟机扩容 虚拟机->设置->硬盘->实用程序->扩展磁盘容量 2 启动Ubuntu系统 2.1 打开终端安装gparted,sudo apt-get install gparted;输入sudo gparted打开gparte…

操作方法:具有多个Mongo存储库和Kotlin的Spring Boot 2 Web应用程序

首先,免责声明:如果您正在编写微服务 (每个人现在都对吗?)并希望它是惯用的 ,那么通常不会在其中使用几个不同的数据源。 图片取自Pixabay© https: //pixabay.com/illustrations/software-binary-sys…

环网工业交换机ERPS技术解析

ERPS(Ethernet Ring Protection Switching,以太环网保护切换协议)是ITU开发的一种环网保护协议,也称G.8032。它是一个专门应用于以太环网的链路层协议。它在以太环网完整时能够防止数据环路引起的广播风暴,而当以太环网上一条链路断开时能迅速…

交换机和路由器的区别是什么?

在我们日常生活中,上网很多时候都要用到交换机和路由器,很多人只知道二者都是用于连接上网的设备,但很少知道它们之间有什么区别,以及各自的功能。 交换机和路由器的区别: 路由器可以给你的局域网自动分配IP&#xf…

apache flume_Flume:使用Apache Flume收集客户产品搜索点击数据

apache flume这篇文章涵盖了使用Apache flume收集客户产品搜索点击并使用hadoop和elasticsearch接收器存储信息。 数据可能包含不同的产品搜索事件,例如基于不同方面的过滤,分类信息,分页信息,以及进一步查看的产品以及某些被客户…

如何选配合适的百兆或者千兆工业交换机

工业上常常会用到工业交换机,工程商在做小型网络监控方案的时候,经常需要选配合适的百兆工业交换机或千兆工业交换机,但是,到底是配百兆工业交换机还是千兆工业交换机呢?如何计算百兆工业交换机和千兆工业交换机的码率…

使用Selenium自动化测试处理多个浏览器选项卡

使用Selenium进行自动化测试一直是将萌芽的自动化测试人员培养为专业人员的生命线。 硒是开源的,在全球范围内被广泛采用。 结果,您会得到社区的大力支持。 有多种用于不同语言的框架,这些框架提供与Selenium的绑定。 因此,您已经…

三层交换机工作原理介绍

每个网络主机、工作站或者服务器都有自己的IP地址和子网掩码。当主机与服务器进行通信的时候,根据自身的IP地址和子网掩码、以及服务器的IP地址,来确定服务器是否和自己处于相同的网段: 1、如果判定在相同网段内,则直接通过地址解…

三层交换机有什么优势?

三层交换机的技术日益成熟,应用日益广泛,在一定范围内,它比路由器更具优势,但是三层交换机与路由器还是有很大的区别,在局域网中,三层交换机有着明显的优势。 1、子网间的传输带宽可以任意分配。 在传统路…

私有环网协议MR-ring介绍

以太网从诞生到今天已经走过了二十几个念头,伴随着IP的大发展,以太网已经一统江湖,98%的局域网采用以太网标准构建。在这二十多年中,以太网不断推陈出新,在速率、安全、稳定性等各方面均有一系列的标准,而环…

网管型工业交换机如何创建网络冗余

与非网管型工业交换机相比,使用杭州飞畅网管型工业交换机的其中一个好处是其冗余功能。这允许您使用带有额外连接的以太网,因此如果网络上两点之间的一条路径出现故障,则可以使用另一条路径来传递消息。如果一个链路或工业交换机发生故障&…

使用var,Lombok和Fluxtion轻松处理事件

介绍 在本文中,我将结合使用Lombok和Fluxtion这两种产品,以演示工具如何在减少代码编写和交付时间的同时提高代码的可读性。 使用Java 10中的var可以进一步改善这种情况。 产品和var都在构建时使用推断来加速开发。 Fluxtion的精神是最大程度地减少浪费…

网管型工业交换机如何提高网路流量过滤?

虽然一个非网管型工业交换机会从一个设备端过滤出许多数据包,但还是有很多数据包非网管型工业交换机无法处理,而这些数据包又必须从端口传输到所有设备上。当一个设备接收到不是特定给该设备的数据包时,它必须先耗费资源来处理这些信息数据最…

html5中meter讲解_Java中的得墨meter耳定律–最少知识原理–实际示例

html5中meter讲解得墨meter耳定律(也称为最少知识定律)是一种编码原理,它表示模块不应该知道其操作的对象的内部细节。 如果代码取决于特定对象的内部细节,则很有可能一旦该对象的内部发生更改,它就会中断。 由于封装是…

网络交换机的分类介绍

从广义上来看,交换机分为两种:广域网交换机和局域网交换机。广域网交换机主要应用于电信领域,提供通信基础平台。而局域网交换机则应用于局域网络,用于连接终端设备,如PC机及网络打印机等。 按照现在复杂的网络构成方…

网络交换机的作用有哪些?

现如今,随着通信业的发展以及国民经济信息化的推进,网络交换机市场呈稳步上升态势,以太网技术已成为当今最重要的一种局域网组网技术,网络交换机也就成为了最普及的交换机。那么,网络交换机的作用有哪些呢?…

网络交换机功能介绍

交换机的主要功能包括物理编址、网络拓扑结构、错误校验、帧序列以及流控。目前交换机还具备了一些新的功能,如对VLAN(虚拟局域网)的支持、对链路汇聚的支持,甚至有的还具有防火墙的功能。 交换机除了能够连接同种类型的网络之外…

HOW-TO:具有MySQL的JEE应用程序中具有集群功能的Quartz Scheduler

Quartz Scheduler是Java世界中最流行的调度库之一。 过去,我主要在Spring应用程序中使用Quartz。 最近,我一直在研究要在云中部署的JBoss 7.1.1上运行的JEE 6应用程序中的调度。 我考虑的一种选择是Quartz Scheduler,因为它提供了与数据库的集…

办公网络对工业交换机的功能要求

如今,随着社会的发展,很多公司对网络的要求越来越高,系统越来越复杂,很多老线路需要改造升级,对工业交换机的要求也越来越高。但是,很多企业并不懂如何改造升级。今天飞畅科技的小编就来为大家详细讲解下公…

工业交换机和工控交换机有什么区别?

众所周知,以太网交换机一般分为:商用(以太网)交换机、工业(以太网)交换机、家用(以太网)交换机,因为我们是专业的工业交换机厂家,在这里着重介绍下工业交换机。 工业交换机一般用在工业生产场合,通常外观和安装形式多…