您的位置:首页 > 编程语言 > Java开发

java基础复习四:for与foreach的循环性能比较

2017-11-17 15:18 621 查看
基本上每次面试都会被问到这个问题,我的回答基本都是foreach性能比for循环好,可是真的是这样么?

常用的遍历类一般是ArrayList、LinkedList、数组,现在实际测试一下。

ArrayList

分别测试一千、一万、十万、百万条数据

测试代码:

public static void main (String[] args) {

List<String> list = new ArrayList<>();
int k = 0;
while (k <= 1000000) {
list.add(String.valueOf(k));
k++;
}
int first = 0;
int second = 0;
for(int m=0; m < 100; m++) {
long start = System.currentTimeMillis();
int size = list.size();
for (int i = 0; i < size; i++) {
System.out.println(list.get(i));
}
first += System.currentTimeMillis() - start;

long startTwo = System.currentTimeMillis();
for (String i : list) {
System.out.println(i);
}
second += System.currentTimeMillis() - startTwo;
}

BigDecimal divior = new BigDecimal(100);
System.out.println("for总耗时" + first + "毫秒");
System.out.println("for平均耗时" + new BigDecimal(first).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
System.out.println("foreach总耗时" + second + "毫秒");
System.out.println("foreach平均总耗时" + new BigDecimal(second).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
}


测试结果:

条数循环类别执行次数总耗时平均耗时
一千for1001163ms11.63ms
一千foreach1001001ms10.01ms
一万for10010749ms107.49ms
一万foreach10010548ms105.48ms
十万for100121296ms1212.96ms
十万foreach100119647ms1196.47ms
百万for1001202435ms12024.35ms
百万foreach1001200809ms12008.09ms
从上面表格可以看出,再遍历ArrayList的时候,for循环与foreach循环性能几乎没有差别(有一点差别,应该是循环体代码造成的)。

所以,可以认为遍历ArrayList两种遍历方式性能是一样的,foreach循环性能并不优于for循环。

数组

测试代码:

public static void main (String[] args) {

String[] list = new String[1000];
int k = 0;
while (k < 1000) {
list[k] = String.valueOf(k);
k++;
}
int first = 0;
int second = 0;
for(int m=0; m < 100; m++) {
long start = System.currentTimeMillis();
int size = list.length;
for (int i = 0; i < size; i++) {
System.out.println(list[i]);
}
first += System.currentTimeMillis() - start;

long startTwo = System.currentTimeMillis();
for (String i : list) {
System.out.println(i);
}
second += System.currentTimeMillis() - startTwo;
}

BigDecimal divior = new BigDecimal(100);
System.out.println("for总耗时" + first + "毫秒");
System.out.println("for平均耗时" + new BigDecimal(first).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
System.out.println("foreach总耗时" + second + "毫秒");
System.out.println("foreach平均总耗时" + new BigDecimal(second).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
}


测试结果:

条数循环类别执行次数总耗时平均耗时
一千for1001134ms11.34ms
一千foreach1001057ms10.57ms
一万for1008957ms89.57ms
一万foreach1009185ms91.85ms
十万for10086097ms860.97ms
十万foreach10088355ms883.55ms
百万for100850238ms8502.38ms
百万foreach100862321ms8623.21ms
和ArrayList一样,for循环与foreach循环性能几乎没有差别。

所以遍历数组,两种遍历方式都可以。

LinkedList

测试代码:

public static void main (String[] args) {

List<String> list = new LinkedList<>();
int k = 0;
while (k < 1000) {
list.add(String.valueOf(k));
k++;
}
int first = 0;
int second = 0;
for(int m=0; m < 50; m++) {
long start = System.currentTimeMillis();
int size = list.size();
for (int i = 0; i < size; i++) {
System.out.println(list.get(i));
}
first += System.currentTimeMillis() - start;

long startTwo = System.currentTimeMillis();
for (String i : list) {
System.out.println(i);
}
second += System.currentTimeMillis() - startTwo;
}

BigDecimal divior = new BigDecimal(100);
System.out.println("for总耗时" + first + "毫秒");
System.out.println("for平均耗时" + new BigDecimal(first).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
System.out.println("foreach总耗时" + second + "毫秒");
System.out.println("foreach平均总耗时" + new BigDecimal(second).divide(divior,2, BigDecimal.ROUND_HALF_UP) + "毫秒");
}


测试结果:

条数循环类别执行次数总耗时平均耗时
一千for50499ms9.98ms
一千foreach50585ms11.70ms
一万for1009099ms181.98ms
一万foreach505096ms101.92ms
十万for100477762ms9555.24ms
十万foreach5049588ms991.76ms
数据对比非常明显,当数据量越来越大的时候,for循环已经不适用于linkedList的遍历了,而foreach还能保持很好的性能。

此时,可以说foreach性能比for好。

总结

1、foreach在遍历LinkedList的时候,性能是明显优于for;

2、在遍历数组和ArrayList的时候,两者没有明显区别;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java