在做效率测试的时候,会发现,在代码里面不起眼的一个for循环,会损失掉不少时间。几种for循环要使用哪个,会效率高点,常用的集合一般都是arrayList,他的循环遍历的效率如何,是不是首选的呢?
开局一张图
然后看这个图的运行代码
package com.lxk.commonTest;
import com.lxk.util.CollectionUtil;
import java.util.List;
/**
* 关于for循环的测试
*
* @author lxk on 2017/4/21
*/
public class ForTest {
private static final int SIZE = 40000;
public static void main(String[] args) {
testForEfficiency();
}
/**
* 测试不同for的效率问题
*/
private static void testForEfficiency() {
String[] array = CollectionUtil.getArray(SIZE);
List<String> arrayList = CollectionUtil.getArrayList(SIZE);
List<String> linkedList = CollectionUtil.getLinkedList(SIZE);
while (true) {
testArray(array);
testArrayList(arrayList);
//testLinkedList(linkedList);
}
}
/**
* array 在使用forI循环的效率测试
*/
private static void testArray(String[] array) {
testForI(array);
testForeach(array);
}
/**
* arrayList 在使用forI循环,forEach循环和lambda循环的效率测试
*/
private static void testArrayList(List<String> arrayList) {
testForI(arrayList);
testForEach(arrayList);
testLambda(arrayList);
}
/**
* linkedList 在使用forI循环,forEach循环和lambda循环的效率测试
*/
private static void testLinkedList(List<String> linkedList) {
testForI(linkedList);
testForEach(linkedList);
testLambda(linkedList);
}
private static void testForI(String[] array) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < SIZE; i++) {
sb.append(array[i]);
}
}
private static void testForeach(String[] array) {
StringBuilder sb = new StringBuilder();
for (String s : array) {
sb.append(s);
}
}
private static void testForI(List<String> arrayList) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < SIZE; i++) {
sb.append(arrayList.get(i));
}
}
private static void testForEach(List<String> arrayList) {
StringBuilder sb = new StringBuilder();
for (String s : arrayList) {
sb.append(s);
}
}
private static void testLambda(List<String> arrayList) {
StringBuilder sb = new StringBuilder();
arrayList.forEach(sb::append);
}
}
先,暂时注释掉linkedList集合的测试代码。
分析一下:
1,数组和集合谁的遍历效率高?
看上面的图,同样的数据,使用ArrayList存储,再遍历最快的占比21.6%,使用数组存储,然后来遍历,时间占比是12.1%。明显是数组循环的时间占比少,所以,数组的遍历效率是比较好的。
2,for i,for each,lambda 三种循环方式,谁好呢?
对于数组来说:我测试的地方数组使用来for i 循环和for each 循环,lambda没得。发现两者是一样的。
同样的数据使用ArrayList去存储,使用三种遍历方式,发现,for each是比较慢的,for i 和lambda的循环效率是差不多的。for i 稍微占点点优势。
然后,打开,linkedList的注释,再来一次。
开局还是一张图
分析一下:
对于linkedList来说,底层是链表结构,for i 循环,是最差的循环方式,
剩下的结论和上面的差不多了
还是数组存储数据,遍历最快,然后就是for i 循环比lambda好一点点,最后是for each循环。
详细展开的图
另:使用的另一个造数据的类
package com.lxk.util;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
/**
* 自定义集合类
*
* @author lxk on 2017/11/13
*/
public class CollectionUtil {
private static final int SIZE = 5;
/**
* 获得底层是数组的list集合
*/
public static List<String> getArrayList(Integer size) {
size = (size == null || size <= 0) ? SIZE : size;
List<String> list = Lists.newArrayListWithExpectedSize(size);
for (Integer i = 0; i < size; i++) {
list.add(i.toString() + "1234567890");
}
return list;
}
/**
* 获得底层是数组的数组
*/
public static String[] getArray(Integer size) {
size = (size == null || size <= 0) ? SIZE : size;
String[] list = new String[size];
for (Integer i = 0; i < size; i++) {
list[i] = (i.toString() + "1234567890");
}
return list;
}
/**
* 获得底层是链表的list集合
*/
public static List<String> getLinkedList(Integer size) {
size = (size == null || size <= 0) ? SIZE : size;
List<String> list = Lists.newLinkedList();
for (Integer i = 0; i < size; i++) {
list.add(i.toString() + "1234567890");
}
return list;
}
/**
* 获得底层是链表的list集合
*/
public static Map<String, String> getMap(Integer size) {
size = (size == null || size <= 0) ? SIZE : size;
Map<String, String> map = Maps.newHashMapWithExpectedSize(size);
for (Integer i = 0; i < size; i++) {
map.put(i.toString(), i.toString());
}
return map;
}
}