【发布时间】: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
Preconditionssource code。 -
我的怀疑是当字符串格式化代码包含在方法中时,HotSpot 不会内联它,这会产生很大的不同。
-
最近有人确认过吗?评论可以追溯到 2009 年 - 也许不再需要这种优化
-
如果我理解正确,它指出
throw new BadException(badMsg(…));比throw constructBadException(…);更快,新异常的实例化发生在constructBadException内。这可能是合理的,因为在后一种情况下将有一个额外的堆栈帧来解析并转换为StackTraceElement,但它主要影响仅微基准,其中堆栈深度通常较低,因此额外的框架会产生影响。对于具有数千个堆栈帧的实际应用程序,多一个没有影响。但这仍然只是一个猜测……
标签: java jvm guava jvm-hotspot