【问题标题】:Java Streams .max() and .min() lag in performance?Java Streams .max() 和 .min() 性能落后?
【发布时间】:2020-08-20 11:36:24
【问题描述】:

考虑以下 2 个示例。

1 使用流

myList.stream().map(this::getInt).max(Integer::compareTo);

2 老办法

int max = Integer.MIN_VALUE;
for (MyItem item : myList) {
    max = Math.max(max, getInt(item));    
}

以上getInt 方法接受MyItem 参数并返回int 结果。

在这里,与 #1 相比,#2 的延迟要低得多。有谁知道我为什么或有什么问题?

【问题讨论】:

  • 声称的性能差异没有记录测量方法是毫无价值的。见How do I write a correct micro-benchmark in Java?,我敢打赌,你违反了一两条规则。一个有用的指针可能是Java lambdas 20 times slower than anonymous classes Q&A。
  • @Holger 你是在建议我用方法输入值吗?
  • 不,我建议记录您如何得出第二个代码比第一个代码“延迟低得多”的结论。如果我们使用测量代码而不是感觉,请发布该代码。然后,我们可以告诉你你做错了什么。或者您可以按照已经发布的链接找到自己。

标签: java java-8 java-stream max min


【解决方案1】:

您可能应该利用 Streams 的功能,这些功能应该可以优化这些情况。阅读 Streams 的文档,第一个示例显示了 IntStream 的优化路径。

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

     int max = myList.stream()
                      .mapToInt(this::getInt)
                      .max()
                      .orElse(Integer.MIN_VALUE);

【讨论】:

  • 我在这里看不到.orElse(Integer.MIN_VALUE); 的任何用途。我错过了什么吗?
  • sum() 对 0 个元素返回 0,max() 返回一个 OptionalInt。
  • max() 返回一个 OptionalInt 如果没有元素则为空。最好坚持使用它而不是将其转换为Integer.MIN_VALUE
  • @YuriSchimke 您的回答很有帮助。但是,这样做并没有给我带来任何显着的性能提升
【解决方案2】:
myList.stream().mapToInt(this::getInt).max()

试试mapping to an IntStreamIntStream 在内部与 ints 一起使用,这避免了装箱和拆箱 Integer 对象的开销。此外,IntStream.max() 不需要自定义比较器。

所以你认为突出的原因是“装箱”和“拆箱”?

如果不通过您的基准运行它,我不知道它是否会匹配for 循环的性能。但这将是一个进步。如果它不够好,那么我建议坚持使用循环,因为我看不到任何其他改进它的方法。

【讨论】:

  • 我实际上尝试了您建议的 int 流方式。但我实际上看不到任何显着的性能改进。
猜你喜欢
  • 1970-01-01
  • 2023-03-19
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 2017-08-06
  • 2017-09-23
  • 2012-08-26
相关资源
最近更新 更多