JAVA在软件测试中用的多不多_Java中foreach使用过多会有性能问题?

最近跟foreach算是很有缘分吧,前一天同事跟我聊一个自己在网上看到的“ foreach使用过多会有性能问题,建议使用for i++来做遍历? ”我当时一听就纳闷了,以前的时候看到文章说JVM对foreach语法糖是有做优化的,在很多博客也是推荐使用foreach的,为什么突然会有这么个说法呢,今天躺床上看到个博客 Java 性能优化的五大技巧 的第五点钟第2条中说“避免使用iterator()”,我决定试试究竟!

9a644483d150449d0fc05a1685a60cd9.png

执行时间(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 iterator() {

return new Itr(); 这部分是比for++多的

}

private class Itr implements Iterator {

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++多那么一点点,迭代器实际返回的是集合的数据集;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值