读编写高质量代码整理(三)-性能

先在下面代码:

 

package performance;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PerformanceTest {
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		int num = 100*10000;
		List container = new ArrayList();
		for(int i=0;i<num;i++) {
			container.add(new Random().nextInt(150));
		}
		
		long start = System.currentTimeMillis();//记录开始时间
		System.out.println("平均数是:"+average(container));
		System.out.println("平均时间:"+(System.currentTimeMillis()-start)+"ms");
		
		long start2 = System.currentTimeMillis();//记录开始时间
		System.out.println("平均数是:"+average2(container));
		System.out.println("平均时间:"+(System.currentTimeMillis()-start2)+"ms");
	}
	//计算平均数
	public static int average(List<Integer> list) {
		int sum = 0;
		for(int i=0;i<list.size();i++) {
			sum+=list.get(i);
		}
		return sum/list.size();
	}
	//计算平均数
	public static int average2(List<Integer> list) {
		int sum = 0;
		for(int i : list) {
			sum+=i;
		}
		return sum/list.size();
	} 
}

输出结果:

平均数是:74
平均时间:23ms
平均数是:74
平均时间:38ms

 question:为什么两种循环的效率相差这么多

我是一个java菜鸟,我写代码的时候看心情的,想到写那个就写那个,以为效率都差不多,没想到。。。呜呜,菜鸟受打击了~

读了Api后才知道ArrayList实现了RandomAccess接口(随机访问呢),这是一个标志性接口,无需任何实现。

foreach方式是iterator(迭代器)的变形用法,等价于

for(Iterator<Integer> iter = list.iterator();i.hashNext;) {
			sum+=i.next();
		}

 迭代器是23种设计模式中的一种,“提供中方法访问一个容器对象的各个元素,同时无需暴露该对象的内部细节”,需要创建一个迭代器容器,然后屏蔽内部细节。但是ArrayList实现了RandomAccess接口,以表明两个对象没有关系,但迭代器缺需要判断是否有下个元素,以及下一个元素是什么等关系,这就是foreach遍历耗时的原因。同理,如果对象之间是有关系的,即是List实现类不是随机存取的,比如LinkedList类,它是一个双向链表,previous node - current node -next node ,此时,使用foreach迭代效率更高。有兴趣的可看下LinkedList的api。重构average方法:

//重构后的方法
	public static int average3(List<Integer> list) {
		int sum = 0;
		if(list instanceof RandomAccess) {
			for(int i=0;i<list.size();i++) {
				sum+=list.get(i);
			}
		}else{
			for(int i : list) {
				sum+=i;
			}
		}
		return sum/list.size();
	}

 

 

 

你可能感兴趣的:(循环 性能)