Java Streams .max() 和 .min() 性能落后?

     2023-03-17     253

关键词:

【中文标题】Java Streams .max() 和 .min() 性能落后?【英文标题】:Java Streams .max() and .min() lag in performance? 【发布时间】: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 你是在建议我用方法输入值吗? 不,我建议记录您如何得出第二个代码比第一个代码“延迟低得多”的结论。如果我们使用测量代码而不是感觉,请发布该代码。然后,我们可以告诉你你做错了什么。或者您可以按照已经发布的链接找到自己。 【参考方案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 流方式。但我实际上看不到任何显着的性能改进。

使用 Java 8 Streams 映射、聚合和组合总计

】使用Java8Streams映射、聚合和组合总计【英文标题】:Mapping,aggregatingandcomposingtotalsusingJava8Streams【发布时间】:2019-10-0320:06:12【问题描述】:我正在尝试重新创建一个进程来创建一个对象列表,这些对象列表是使用Java8流的另一... 查看详情

java8不止是lambdas和streams

转眼淘系应用升级JDK8已经几个月过去了,Lambdas表达式和Streams APIs的确给同学们带来了编程效率和代码可读性上的提升,代码变得更加简洁直接,更加符合人的思维(看来编程语言的发展也是本着“以人为本”的思路)... 查看详情

使用 JDK8 和 lambda (java.util.stream.Streams.zip) 压缩流

】使用JDK8和lambda(java.util.stream.Streams.zip)压缩流【英文标题】:ZippingstreamsusingJDK8withlambda(java.util.stream.Streams.zip)【发布时间】:2013-07-1212:30:53【问题描述】:在带有lambdab93的JDK8中,有一个类java.util.stream.Streams.zipinb93可用于压缩流... 查看详情

如何使用 Java Streams API 添加和更新地图条目

】如何使用JavaStreamsAPI添加和更新地图条目【英文标题】:HowtoaddandupdatemapentryusingJavaStreamsAPI【发布时间】:2021-12-1904:24:37【问题描述】:我刚开始学习Streams,我的任务是对某个字符串数组中的所有单词进行计数和排序。我已经... 查看详情

java8的streams

首先看一个问题:在这个task集合中一共有多少个OPEN状态的?计算出它们的points属性和。在Java8之前,要解决这个问题,则需要使用foreach循环遍历task集合;但是在Java8中可以利用steams解决:包括一系列元素的列表,并且支持顺序... 查看详情

Java 8 Streams - 收集与减少

】Java8Streams-收集与减少【英文标题】:Java8Streams-collectvsreduce【发布时间】:2014-04-2921:48:33【问题描述】:您什么时候使用collect()和reduce()?有没有人有好的、具体的例子说明什么时候选择一种方式肯定更好?Javadocmentionsthatcollect... 查看详情

使用 Java Streams 和 Spring Boot 的 RESTful Web 服务

】使用JavaStreams和SpringBoot的RESTfulWeb服务【英文标题】:RESTfulwebserviceusingJavaStreamsandSpringBoot【发布时间】:2020-07-0815:10:07【问题描述】:我尝试实现一个RESTfulWebService,它能够直接从数据库中流式传输数百万条记录。我正在使用Sp... 查看详情

使用 Java 8 Streams 从列表中仅获取所需的对象

】使用Java8Streams从列表中仅获取所需的对象【英文标题】:GettingonlyrequiredobjectsfromalistusingJava8Streams【发布时间】:2015-11-1422:19:42【问题描述】:考虑一个具有attrib1、attrib2和List<Child>属性的Parent子类及其对应的getter和se... 查看详情

使用 Streams 实现 Java Pivot 表

】使用Streams实现JavaPivot表【英文标题】:ImplementingJavaPivottableusingStreams【发布时间】:2022-01-2403:39:01【问题描述】:这几天我一直在努力解决这个问题。我正在尝试使用JavaStreams创建Pivot功能。我只需要执行总和、计数、最大值... 查看详情

将 Streams 与原始数据类型和相应的包装器一起使用

】将Streams与原始数据类型和相应的包装器一起使用【英文标题】:UsingStreamswithprimitivesdatatypesandcorrespondingwrappers【发布时间】:2014-05-2507:17:40【问题描述】:在使用Java8的Streams-API时,我偶然发现了以下问题:要将原始包装类对... 查看详情

使用 Streams 展平 Java 对象

】使用Streams展平Java对象【英文标题】:FlattenJavaObjectusingStreams【发布时间】:2019-12-0407:24:11【问题描述】:我有这样的课:classStudentStringname;Stringage;List<Course>Courses;classCourseStringcourseName;Stringteacher;我有:List<Student>stud 查看详情

Java 8 Streams - 分组为单个值[重复]

】Java8Streams-分组为单个值[重复]【英文标题】:Java8Streams-GroupingintoSinglevalue[duplicate]【发布时间】:2017-08-2513:50:44【问题描述】:我目前正在使用List&lt;Map&lt;String,Object&gt;&gt;,我正在尝试对地图中的各种键进行分组。... 查看详情

Hashmap with Streams in Java 8 Streams 收集 Map 的值

】HashmapwithStreamsinJava8Streams收集Map的值【英文标题】:HashmapwithStreamsinJava8StreamstocollectvalueofMap【发布时间】:2015-06-1922:56:46【问题描述】:让我们考虑一个哈希图Map<Integer,List>id1=newHashMap<Integer,List>();我在两个哈希图中都... 查看详情

Parallel Streams 和 forkjoinpool 在生产环境中使用是不是安全?

】ParallelStreams和forkjoinpool在生产环境中使用是不是安全?【英文标题】:AreParallelStreamsandforkjoinpoolsafetouseinProduction?ParallelStreams和forkjoinpool在生产环境中使用是否安全?【发布时间】:2017-04-2008:28:58【问题描述】:我们开发了一... 查看详情

Streams 和 Firehose 的用例是啥?

】Streams和Firehose的用例是啥?【英文标题】:What\'stheusecasesofStreamsandFirehose?Streams和Firehose的用例是什么?【发布时间】:2021-01-1312:18:09【问题描述】:我正在开发一个可以读取和分析支付交易日志的应用程序。我知道我会根据我... 查看详情

为啥 Files.lines(和类似的 Streams)不会自动关闭?

】为啥Files.lines(和类似的Streams)不会自动关闭?【英文标题】:WhyisFiles.lines(andsimilarStreams)notautomaticallyclosed?为什么Files.lines(和类似的Streams)不会自动关闭?【发布时间】:2016-03-0810:09:46【问题描述】:Stream状态的javadoc:Stre... 查看详情

环形数组最大子段和dp

...情况。1.最大和的这个子段没有包含头尾。所以直接dp[i]=max(dp[i-1]+a[i],a[i])2.最大和的这个子段包含了头尾。这个时候,最大和=累积和-连续子段最小和。然后比较两种情况的大小,输出大的那一个就行。#include<bits/stdc++.h>#def... 查看详情

Java 8 Streams 中的过滤器映射

】Java8Streams中的过滤器映射【英文标题】:filterMapinJava8Streams【发布时间】:2018-01-0120:53:02【问题描述】:我试图使用StreamsAPI过滤HashMap中的条目,但停留在最后一个方法调用Collectors.toMap。所以,我不知道实现toMap方法publicvoidfilt... 查看详情