【问题标题】:Please explain Hotspot optimization refactor from Preconditions.java in guava code base?请解释 guava 代码库中 Preconditions.java 的热点优化重构?
【发布时间】:2017-03-22 02:17:47
【问题描述】:

我正在浏览 Guava 代码库和in Preconditions source there is some explanation,如下所示:

所有最近的热点(截至 2009 年)真的喜欢自然 代码

if (guardExpression) {
  throw new BadException(messageExpression);
}

重构,以便将 messageExpression 移动到单独的 字符串返回方法。

if (guardExpression) {
   throw new BadException(badMsg(...));
}

可选的自然重构为 void 或 Exception-returning 方法要慢得多。这是一个大问题 - 我们正在谈论因素 微基准测试中的 2-8,而不仅仅是 10-20%。 (这里是热点 优化器错误,应该修复,但这是一个单独的大问题 项目)。

上面的编码模式在 java.util 中被大量使用,例如在 数组列表。 JDK中有一个RangeCheckMicroBenchmark 那是用来测试的。

但是这个类中的方法要抛出不同的异常, 取决于参数,所以看起来这种模式不是 直接适用。但我们可以使用可笑的诡计 在另一个构造过程中抛出异常 例外。热点很好。

它适用于哪些 jvm?为什么这么慢,我不明白?作为开发人员,这对我意味着什么?它是否仍然适用于 oracle 和 openjdk 的 java8 jvm?在编写代码时如何利用这条信息?

【问题讨论】:

  • 这实际上是一个很酷的想法,可以继续阅读和思考,尽管我在这里看不到您的问题。能不能问的更清楚一点?
  • @JonSkeet 这是一个excerpt from Preconditions source code
  • 我的怀疑是当字符串格式化代码包含在方法中时,HotSpot 不会内联它,这会产生很大的不同。
  • 最近有人确认过吗?评论可以追溯到 2009 年 - 也许不再需要这种优化
  • 如果我理解正确,它指出throw new BadException(badMsg(…));throw constructBadException(…); 更快,新异常的实例化发生在constructBadException 内。这可能是合理的,因为在后一种情况下将有一个额外的堆栈帧来解析并转换为StackTraceElement,但它主要影响仅微基准,其中堆栈深度通常较低,因此额外的框架会产生影响。对于具有数千个堆栈帧的实际应用程序,多一个没有影响。但这仍然只是一个猜测……

标签: java jvm guava jvm-hotspot


【解决方案1】:

适用于哪些jvm?

HotSpot - Oracle 的 JVM 实现

为什么慢,我看不懂?

这是 JVM 实现的特性。没有特别的原因(就 JLS/JVMS 而言)为什么它应该更慢,但截至上次有人分析它时,确实如此。您找到的RangeCheckMicroBenchmark 类有更多详细信息和示例。

这对我作为开发人员意味着什么?

什么都没有。除非你正在实现一个像Preconditions 这样的类——它有数百万次使用,都需要尽可能接近零开销——你没有理由担心这个细节。这就是为什么它是代码注释,而不是 Javadoc 注释。

oracle 和 openjdk 是否仍然适用于 java8 jvm?

可能,是的。该评论未链接到特定的 HotSpot 错误,但您也许可以在 JDK 邮件列表中搜索提及的基准代码并找到相关错误。

如果 JVM 的行为发生变化,Preconditions 很可能会被更新。

在编写代码时如何利用这条信息?

真的没有必要这样做。如果您最终编写 Guava 2.0,您将(希望)运行您自己的基准测试,并且会发现值得以这种方式修复的瓶颈。尝试在不严格对自己的代码进行基准测试的情况下利用微优化可能弊大于利。

【讨论】:

  • Java 9 有一个等效的 jdk.internal.util.Preconditions,它遵循 20 岁的 ArrayList 代码的模式;异常构造未内联到进行检查的方法中。此功能通过java.util.Objects 的公共 API 公开,显然,一旦迁移到 Java 9,使用这些方法是应用程序程序员的最佳选择。
猜你喜欢
  • 1970-01-01
  • 2019-05-03
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-19
相关资源
最近更新 更多