List与Set生成的Stream执行anyMatch的性能差异是否显著
List与Set的Stream#anyMatch性能差异解答
你示例中的两个anyMatch调用不存在显著的性能差异,你实测的100万次执行30ms差值属于正常的测量误差,大概率来自JVM预热、GC干扰、系统调度等非核心逻辑的影响。
核心原因如下:
anyMatch是短路终止操作,遍历到第一个符合条件的元素就会直接停止执行,不会遍历整个集合。你示例中第二个元素就是偶数,不管是List还是Set的Stream都只会遍历前2个元素就返回结果,遍历成本几乎一致。- 你示例中使用的
List.of、Set.of创建的是JDK内置的不可变集合,小容量场景下二者内部都是基于数组存储元素,Stream遍历逻辑都是顺序遍历数组,执行路径几乎没有区别。
特殊场景下的微小差异说明:
如果是日常开发常用的ArrayList和HashSet场景,二者的Stream遍历会有可观测但通常不显著的差异:ArrayList的底层是连续的对象数组,Stream遍历时直接顺序扫描数组即可,没有额外开销;HashSet底层是哈希表,存在一定比例的空槽位,遍历时需要跳过空槽,会产生少量额外开销。但只要不是容量极大、负载因子极低的极端场景,这种差异在业务开发中几乎可以忽略,尤其是anyMatch短路的情况下,差异会被进一步缩小。
如果要做精准的性能对比,推荐使用JMH(Java Microbenchmark Harness)工具进行测试,它会自动处理JVM预热、代码分层编译、GC干扰等问题,得到的结果会比自行循环执行更准确。
你使用的测试代码参考:
List<Integer> list = List.of(1, 2, 3, 4); Set<Integer> set = Set.of(1, 2, 3, 4); var result1 = list.stream().anyMatch(i -> (i % 2 == 0)); var result2 = set.stream().anyMatch(i -> (i % 2 == 0));
内容的提问来源于stack exchange,提问作者kasopey
相关产品推荐
相关产品推荐

