Java中foreach使用过多会有性能问题?
作者:网络转载 发布时间:[ 2016/12/13 11:18:30 ] 推荐标签:测试开发技术 Java
近跟foreach算是很有缘分吧,前同事跟我聊一个自己在网上看到的“ foreach使用过多会有性能问题,建议使用for i++来做遍历? ”我当时一听纳闷了,以前的时候看到文章说JVM对foreach语法糖是有做优化的,在很多博客也是推荐使用foreach的,为什么突然会有这么个说法呢,躺床上看到个博客 Java 性能优化的五大技巧 的第五点钟第2条中说“避免使用iterator()”,我决定试试究竟!
执行时间(1000*1000数据量)
ArrayLIst的遍历时间对比( 实验结果证明foreach要比for++要差那么些,但是非常接近 )
long start = System.currentTimeMillis();
for (int i = 0; i < list.size(); i ++) {
String s = list.get(i);
}
System.out.println("arrayList for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : list) {
//
}
System.out.println("arrayList foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
执行结果:
第1次:
arrayList for i++ on 1000*1000 records time waste: 0
arrayList foreach on 1000*1000 records time waste: 16
第2次:
arrayList for i++ on 1000*1000 records time waste: 0
arrayList foreach on 1000*1000 records time waste: 0
第3次:
arrayList for i++ on 1000*1000 records time waste: 0
arrayList foreach on 1000*1000 records time waste: 0
LinkedLIst的遍历时间对比( 实验结果证明foreach要比for++好N多数量级倍,N具体多少取决于数据量 )
for (int i = 0; i < list.size(); i ++) {
String s = list.get(i);
}
System.out.println("LinkedList for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : list) {
//
}
System.out.println("LinkedList foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
实验结果
第一次:
LinkedList for i++ on 1000*1000 records time waste: 41224
LinkedList foreach on 1000*1000 records time waste: 11
第二次:
LinkedList for i++ on 1000*1000 records time waste: 43914
LinkedList foreach on 1000*1000 records time waste: 11
第三次:
LinkedList for i++ on 1000*1000 records time waste: 57320
LinkedList foreach on 1000*1000 records time waste: 16
Array的遍历时间对比( 实验结果证明foreach要比for++要差那么些,但是非常接近,与ArrayList竟然那么相似 )
String[] array = (String[])list.toArray(new String[]{});
long start = System.currentTimeMillis();
for (int i = 0; i < array.length; i ++) {
String s = array[i];
}
System.out.println("Array for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : array) {
//
}
System.out.println("Array foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
实验结果
第一次:
Array for i++ on 1000*1000 records time waste: 0
Array foreach on 1000*1000 records time waste: 0
第二次:
Array for i++ on 1000*1000 records time waste: 0
Array foreach on 1000*1000 records time waste: 16
第三次:
Array for i++ on 1000*1000 records time waste: 0
Array foreach on 1000*1000 records time waste: 0
foreach比for++费内存?
先引用一位哥们的说法:
every time you run into this loop, if strings is an Iterable, you will create a new Iterator instance. If you’re using an ArrayList, this is going to be allocating an object with 3 ints on your heap、浪费空间啊。
关于耗费内存的说法我是支持的,但是” with 3 ints on your heap “这个我不能同意了,foreach语法糖实际是JVM根据对象生成一个迭代器,我们来看下源码,看下是不是多浪费了空间,浪费了多少空间,现以java.util.ArrayList为例:
public Iterator<E> iterator() {
return new Itr(); ////这部分是比for++多的
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification(); //这部分是比for++多的
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
由代码可见,foreach比for++多了new了一个对象,遍历的时候多了是否遍历种被修改判断,其余操作与for++是一致的。由此可见:多浪费空间一说是纯属扯蛋。
总结
1、foreach遍历线性集合对象比for++略低,但差距非常接近;
2、foreach遍历链表集合对象比for++高的多,差距由集合对象数量决定
3、foreach遍历内存使用上会比for++多那么一点点,迭代器实际返回的是集合的数据集;
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11