开发中数据处理常用到遍历,Java 为遍历提供了 for 和 foreach,lambda 表达式 foreach,stream 流 foreach,今天对这几种使用做个简单测试。
测试 Array ,ArrayList,LinkedList 三种数据结构。
Java 8 Stream API 性能测试,这篇文章中的测试更合理全面。
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| import java.util.ArrayList; import java.util.LinkedList; import java.util.List;
public class ForTest {
public static void main(String[] args) { forArray(); forArrayList(); forLinkList(); }
public static void forArray() { Integer[] numArray = new Integer[5000000]; for (int i = 0; i < 5000000; i++) { numArray[i] = i; }
Long start = System.currentTimeMillis(); for (int i = 0; i < numArray.length; i++) { Integer integer = numArray[i]; } System.out.print("Array for:"); System.out.println(System.currentTimeMillis() - start);
Long start2 = System.currentTimeMillis(); for (Integer num : numArray) {
} System.out.print("Array foreach:"); System.out.println(System.currentTimeMillis() - start2);
}
public static void forArrayList() { List<Integer> list = new ArrayList<>(5000000); for (int i = 0; i < 5000000; i++) { list.add(i); }
Long start = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { list.get(i); } System.out.print("ArrayList for:"); System.out.println(System.currentTimeMillis() - start);
Long start2 = System.currentTimeMillis(); for (Integer num : list) {
} System.out.print("ArrayList foreach:"); System.out.println(System.currentTimeMillis() - start2);
Long start3 = System.currentTimeMillis(); list.forEach(e -> {}); System.out.print("ArrayList lambada foreach:"); System.out.println(System.currentTimeMillis() - start3);
Long start4 = System.currentTimeMillis(); list.stream().forEach(p ->{}); System.out.print("ArrayList stream foreach:"); System.out.println(System.currentTimeMillis() - start4);
}
public static void forLinkList() { LinkedList<Integer> list = new LinkedList<>(); for (int i = 0; i < 200000; i++) { list.add(i); }
Long start = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { list.get(i); } System.out.print("LinkList for:"); System.out.println(System.currentTimeMillis() - start);
Long start2 = System.currentTimeMillis(); for (Integer num : list) {
} System.out.print("LinkList foreach:"); System.out.println(System.currentTimeMillis() - start2);
Long start3 = System.currentTimeMillis(); list.forEach(e ->{}); System.out.print("LinkList lambda foreach:"); System.out.println(System.currentTimeMillis() - start3);
Long start4 = System.currentTimeMillis(); list.stream().forEach(p -> {}); System.out.print("LinkList stream foreach:"); System.out.println(System.currentTimeMillis() - start4); } }
|
结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| Array for:2 Array foreach:2 ArrayList for:3 ArrayList foreach:13 ArrayList lambada foreach:43 ArrayList stream foreach:13 LinkList for:14931 LinkList foreach:3 LinkList lambda foreach:4 LinkList stream foreach:2
Array for:2 Array foreach:2 ArrayList for:3 ArrayList foreach:15 ArrayList lambada foreach:43 ArrayList stream foreach:13 LinkList for:14335 LinkList foreach:4 LinkList lambda foreach:7 LinkList stream foreach:2
Array for:2 Array foreach:2 ArrayList for:4 ArrayList foreach:13 ArrayList lambada foreach:41 ArrayList stream foreach:12 LinkList for:14206 LinkList foreach:5 LinkList lambda foreach:4 LinkList stream foreach:2
|
结论
- Array :for 和 foreach 遍历是极快。
- ArrayList :for 最快;其次是 stream.forEach() ,foreach 略差点,但不多;lambada forEach() 最慢,且慢很多。
- LinkList:stream.forEach() 最快;其次是 foreach 和 lambada forEach(),两者相差不大;最差且极差的是 for,这是底层实现方法决定的。
选择:数组类型优先选择for
循环遍历,其次是 stream.forEach()
;链表类型优先选择 stream.forEach()
,决不能使用 for
循环遍历。