【问题标题】:Cached Optional<Boolean> values缓存的 Optional<Boolean> 值
【发布时间】:2015-02-26 09:06:25
【问题描述】:

对于标准库中可用的truefalse 值,似乎没有任何Optional&lt;Boolean&gt; 类型的缓存对象。我在某个地方想念他们吗?

如果没有这样的对象,我会感到惊讶,因为在我看来,这对于清晰度和性能来说都非常有用。

如果真的没有这样的对象,那是为什么呢?

【问题讨论】:

标签: java boolean java-8 optional


【解决方案1】:

在 Java 8 中,他们改进了对象创建的优化,特别是对于像 Optional 这样的短期对象。 JIT 可以做的是使用转义分析通过将它们的字段放在堆栈上来消除短期对象。在Optional&lt;Boolean&gt; 的情况下,这很可能最多只能上交boolean

请参阅以下关于对象消除的文章,如何检测它不起作用以及您可以采取哪些措施。 Java Lambdas and Low Latency

相反的问题是,为什么要有 OptionalInt、OptionalLong 和 OptionalDouble?这些可能有用,只是没有你想象的那么有用。与Boolean 不同,并非所有IntegerLongDouble 值都被缓存,虽然Escape Analisys 可以消除对象,但它很昂贵并且可能需要一段时间才能启动,可能永远不会因为代码运行时间不够长。

【讨论】:

  • 逃逸分析当然是一个很好的想法,但我已经阅读了很多关于依赖它的警告,例如来自 Stuart Mark 关于与 Project Lambda 相关的其他主题。 EA 仅在简单的程序内案例中可靠地工作。
  • @Lii 正确,尽管 Optional 通常用于简单的方法内情况。它很少分配给我想像的领域。
  • @Lii:Optional 的预期用例完全适合 EA,即由操作创建和返回(例如 find),然后由直接调用者查询和删除。
  • @Holger:嗯,也许,我不确定。 EA 系统真的可以返回栈上的对象吗?还是只有在被调用的方法被内联时才会启动?我怀疑是后者。流库也有很多间接和深度调用堆栈,我怀疑 EA 在那里用处不大。
  • 我想这里的底线是它可能会设法删除对象创建,但你真的不能指望它。
【解决方案2】:

没有理由将特定的优化策略固定到 API 中。 Optional 实例是通过工厂方法获取的,它关于返回的对象身份的行为是故意未指定的。

所以实现可以在内部有一个缓存设施,但也可能是 JVM 的优化器会处理这些事情。今天的 JVM 已经尽可能避免在热点中创建实例,但未来的 JVM 实现也可能会为 “value based classes” 注入缓存或重复数据删除工具。

另见“Why should I not use identity based operations on Optional in Java8?”

【讨论】:

  • 另一方面,要在工厂方法Optional.of 中实现Optional&lt;Boolean&gt; 的缓存,必须在每个 情况下测试参数的类型。如果Optional&lt;Boolean&gt; 有特定的常量,客户端可以直接选择。
  • 虽然这个问题的明确答案必须参考来自其中一位设计师的开发邮件列表,但在我看来,这个可能性更大。
  • 附带说明,使用boolean 值的自动装箱编译代码也会生成调用Boolean.valueOf 的代码,而不是直接访问常量Boolean.TRUEBoolean.FALSE。统一处理所有案例使事情变得更容易......
  • 也许有一天我们会自动装箱Optional。甚至user defined autoboxing.
  • @Lii:链接的 C# 功能只是定义了如何在源代码中处理转换。对于 JVM 端优化,不需要这样的东西。它所需要的只是知道某些工厂方法具有该值类型语义并且可能会被特殊处理(即使在今天也有很多)。可能有一个基于注释的解决方案来标记此类工厂方法,但实际上,当您遵守不应该关心返回对象的身份的合同时,JVM 已经具备了确定这些对象的基于值的性质所需的一切代码分析。
猜你喜欢
  • 1970-01-01
  • 2021-06-05
  • 2016-08-19
  • 2022-11-03
  • 2011-03-27
  • 2011-09-07
  • 1970-01-01
  • 2013-01-29
  • 2013-09-04
相关资源
最近更新 更多