遍历一个List对象的方法不外乎有三种:
使用Iterator、get(i)、for each
如下测试一下这三种方法的性能如何:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
public class PeformanceTest {
/**
* 采用迭代器遍历列表
*
* @param list
* 待遍历的列表
* @return 遍历耗时
*/
public static long iteratorEnum(List<Integer> list) {
long beginTime = System.currentTimeMillis();
Iterator<Integer> it = list.iterator();
long result = 0;
for (; it.hasNext();) {
result += it.next().longValue();
}
long endTime = System.currentTimeMillis();
return endTime - beginTime;
}
/**
* 采用get方法遍历列表
*
* @param list
* 待遍历的列表
* @return 遍历耗时
*/
public static long getEnum(List<Integer> list) {
long beginTime = System.currentTimeMillis();
long result = 0;
for (int i = 0, size = list.size(); i < size; i++) {
result += list.get(i).longValue();
}
long endTime = System.currentTimeMillis();
return endTime - beginTime;
}
/**
* 采用for each方法遍历列表
*
* @param list
* 待遍历的列表
* @return 遍历耗时
*/
public static long forEnum(List<Integer> list) {
long beginTime = System.currentTimeMillis();
long result = 0;
for (Integer b : list) {
result += b.longValue();
}
long endTime = System.currentTimeMillis();
return endTime - beginTime;
}
/**
* 填充一个列表
*
* @param list
* 待填充的列表
* @param length
* 填充的数据长度
* @return 填充完毕的列表
*/
public static List<Integer> filledList(List<Integer> list, int length) {
if (list != null) {
for (int i = 0; i < length; i++) {
list.add(Integer.valueOf(0));
}
}
return list;
}
/**
* 列表遍历性能测试
*
* @param length
* 列表长度
* @param times
* 遍历次数
*/
public static void testPerformance(int length, int times) {
List<Integer> arrayList = new ArrayList<Integer>();
filledList(arrayList, length);
List<Integer> vectorList = new Vector<Integer>();
filledList(vectorList, length);
List<Integer> linkedList = new LinkedList<Integer>();
filledList(linkedList, length);
System.out.println("ArrayList");
testListPerformance(arrayList, times);
System.out.println("Vector");
testListPerformance(vectorList, times);
System.out.println("LinkedList");
testListPerformance(linkedList, times);
}
/**
* 测试列表的各种遍历方法的耗时
*
* @param times
* 遍历次数
*/
public static void testListPerformance(List<Integer> list, int times) {
long it = 0;
for (int i = 0; i < times; i++) {
it += iteratorEnum(list);
}
long get = 0;
for (int i = 0; i < times; i++) {
get += getEnum(list);
}
long lfor = 0;
for (int i = 0; i < times; i++) {
lfor += forEnum(list);
}
System.out.println("it:" + it + "\tget:" + get + "\tfor:" + lfor);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testPerformance(1000, 10000);
}
}
机器配置:
Intel(R) Core(TM)2 Duo CPU T7250 @ 2.00GHz 1.00GHz, 2.00GB的内存物理地址扩展
测试结果:
ArrayList
it:516 get:172 for:500
Vector
it:1375 get:750 for:1343
LinkedList
it:266 get:4422 for:250
说明:多次运行,每个数值的偏差都不超过5%
结论:
非LinkedList使用get方法遍历,该方法本身就是从数组中直接取数;
对于LinkedList,采用Iterator和for each方法可以极大提高遍历速度。关于采用Iterator还是for each方法,可参考《Effective Java》第46条。