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

来源:互联网 发布:java dom4j解析xml 编辑:程序博客网 时间:2024/06/05 10:39

基本上每次面试都会被问到这个问题,我的回答基本都是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) + "毫秒");    }

测试结果:

条数 循环类别 执行次数 总耗时 平均耗时 一千 for 100 1163ms 11.63ms 一千 foreach 100 1001ms 10.01ms 一万 for 100 10749ms 107.49ms 一万 foreach 100 10548ms 105.48ms 十万 for 100 121296ms 1212.96ms 十万 foreach 100 119647ms 1196.47ms 百万 for 100 1202435ms 12024.35ms 百万 foreach 100 1200809ms 12008.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) + "毫秒");    }

测试结果:

条数 循环类别 执行次数 总耗时 平均耗时 一千 for 100 1134ms 11.34ms 一千 foreach 100 1057ms 10.57ms 一万 for 100 8957ms 89.57ms 一万 foreach 100 9185ms 91.85ms 十万 for 100 86097ms 860.97ms 十万 foreach 100 88355ms 883.55ms 百万 for 100 850238ms 8502.38ms 百万 foreach 100 862321ms 8623.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) + "毫秒");    }

测试结果:

条数 循环类别 执行次数 总耗时 平均耗时 一千 for 50 499ms 9.98ms 一千 foreach 50 585ms 11.70ms 一万 for 100 9099ms 181.98ms 一万 foreach 50 5096ms 101.92ms 十万 for 100 477762ms 9555.24ms 十万 foreach 50 49588ms 991.76ms

数据对比非常明显,当数据量越来越大的时候,for循环已经不适用于linkedList的遍历了,而foreach还能保持很好的性能。

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

总结

1、foreach在遍历LinkedList的时候,性能是明显优于for;
2、在遍历数组和ArrayList的时候,两者没有明显区别;

阅读全文
0 0