【问题标题】:java inline Streams and Optional<T> at compile time编译时的 java inline Streams 和 Optional<T>
【发布时间】:2018-01-16 11:01:18
【问题描述】:

由于可读性,我非常喜欢 Java 8 的特性,但我担心它们可能会导致性能下降。虽然从长远来看,由于 JIT,它可能不会影响应用程序的速度,但它可能会影响内存使用,这是我最关心的问题之一。 IntelliJ IDEA 提供了将 Stream API 使用转换为循环的选项(用于单次使用)。 有没有办法在我每次构建项目时内联所有这些功能?

例如,如果我使用find("my-record").ifPresent(records::add),我希望这些更改:Optional&lt;Record&gt; find(String) 的签名将转换为(可空)Record find(String),并且方法调用将转换为空检查。

注意:我知道流和循环之间存在大量细微差别,但我将代码设计为不依赖于实现细节。

【问题讨论】:

  • “可能 [...] 它可能会影响内存使用”您是否有任何迹象表明这确实(在很大程度上)适用于您的具体情况?
  • 流倾向于创建相当多的对象、循环和“如果”不创建,对吗?此外,有几个基准(看起来可信),其中小型流可以慢 5 倍以上。
  • 这意味着此功能会将被调用方法的返回类型从Optional&lt;Record&gt; 调整为Record 以及对它的所有调用。这是一个有问题的方法,因为它依赖于使用该功能构建的被调用者的所有依赖项。
  • 你真的有性能问题吗?看起来像是过早优化的情况。
  • 我会担心find 方法实际上做了什么,而不是它如何返回结果。你肯定看错了。

标签: java optimization build java-8


【解决方案1】:

正如我在评论中链接到的所有类似问题中所解释的,Java8 SDK 本身不提供在编译时添加此类优化的方法。

Java 9“提前”编译器可以inline more aggressively

此处设想的优化技术包括但不包括 仅限于:快速查找 JDK 和应用程序类;早期的 字节码验证;激进的内联,例如 lambda 表达式和其他标准编译器优化; [...]

ProGuard 也做了一些内联:

在优化步骤中,ProGuard 进一步优化了代码。之中 其他不是入口点的优化、类和方法可以 设为私有、静态或最终,可以删除未使用的参数, 并且某些方法可能是内联的。

【讨论】:

  • 感谢您的回答,我对对象内联 比简单的函数内联更感兴趣。但是 AOT 肯定看起来很有希望,至少在某些情况下(我知道它的缺点)。感谢 ProGuard - 以前从未使用过,但似乎是一个有用的工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多