每日一例 | forEach、forItem和forI的性能测试
共 3677字,需浏览 8分钟
·
2021-05-28 14:03
前言
日常开发中,for
循环是我们最常用的循环之一,我们经常用他们来遍历各种集合,除了forI
这种最基本的for
循环,还有forItem
这种增强的for
循环,而且随着lambda
表达式的诞生,jdk
还为我们提供了另外一种循环遍历方式——forEach
,但是我一直有个疑问,到底他们的性能如何呢,实际开发中我们应该如何选择呢?今天,我们就来探讨下这个问题。
性能测试
准备
开始之前,我们先写一段测试代码,这段代码的作用就是构建一个String
的List
,然后我们分别用他们三个进行循环遍历,分别计算用时
public static void main(String[] args) {
int initSize = 100;
List<String> stringList = new ArrayList<>(initSize);
for (int i = 0; i < initSize; i++) {
stringList.add(String.format("%d%s", i, "str"));
}
// forEach
long startTimeForEach = System.currentTimeMillis();
stringList.forEach(System.out::println);
long endTImeForEach = System.currentTimeMillis();
// for item
long startTimeForItem= System.currentTimeMillis();
for (String s : stringList) {
System.out.println(s);
}
long endTimeForItem= System.currentTimeMillis();
// for i
long startTimeForI= System.currentTimeMillis();
for (int i = 0; i < stringList.size(); i++) {
System.out.println(stringList.get(i));
}
long endTimeForI= System.currentTimeMillis();
System.out.println(String.format("List为%d时,forEach遍历用时:%d", initSize, (endTImeForEach - startTimeForEach)));
System.out.println(String.format("List为%d时,forItem遍历用时:%d", initSize, (endTimeForItem - startTimeForItem)));
System.out.println(String.format("List为%d时,forI遍历用时:%d", initSize, (endTimeForI - startTimeForI)));
}
开始测试
初始值为100
我们先把List
的初始化大小设为100
,测试的结果表明,在此等数据量下,forI
和forItem
的用时基本一致,多次运行,偶尔,forI
表现会更好一点,但是forEach
的时间性能就没那么优秀了,和前两都有着数量级的区别:
初始值为1,000
这时候,forI
和forItem
的差距就体现出来了,后者比前者快了近一倍,当然,forEach
性能依然表现最差。和100
时相比,forI
用时翻了6
倍,forItem
用时翻了5
倍,forEach
用时翻了不到两倍。
重复多次运行,forItem
和forI
有差距,稳定在20
左右,但不是很大,forEach
稳定在200
左右
初始值10,000
这时候的性能表现,竟然是forI
最优,当然依然是forEach
最差
多次运行也基本维持这个结论
初始值100,000
数据量达到十万的时候,forEach
才慢慢开始有优势了,但是还是超不过forI
偶尔会有和结论相悖的结果的,但这种情况很少
大部分都是符合我们结论的
LinkedList
但如果把ArrayList
改成LinkedList
,数据量超过10,000
基本上都是forI
表现最差
100,000时
10,000
1000
这里还是forEach
最差
100
forI
最好
总结
上面的结论已然很直观了,综合表现forI
最佳,forItem
其次,最差的是forEach
,但并不是说以后开发就只推荐你用forI
,其实还是要看你具体业务的,如果你要用lambda
表达式,那forEach
就是最好的选择,你也没得选。当然,以上测试结果可能和环境也有关系(JDK1.8
),毕竟12
年的老爷机了,要啥自行车……