読み書き高品質コード整理(三)-性能


まず、次のコードを使用します.
 
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:なぜ2つのサイクルの効率がこんなに悪いのですか.
私はjava菜鸟で、私はコードを书く时気持ちを见て、それを书くと思ってそれを书いて、効率があまり悪くないと思って、思いもよらなかった...うわっ、菜鳥がショック~
Apiを読んでからArrayListがRandomAccessインタフェース(ランダムアクセス)を実現していることがわかりました.これはシンボルインタフェースで、何の実現も必要ありません.
foreach方式はiterator(反復器)の変形用法であり、
for(Iterator<Integer> iter = list.iterator();i.hashNext;) {
			sum+=i.next();
		}

反復器は23の設計モードの1つで、「提供中メソッドは、オブジェクトの内部の詳細を露出することなく、コンテナオブジェクトの各要素にアクセスします」と、反復器コンテナを作成し、内部の詳細を遮断する必要があります.しかし、ArrayListはRandomAccessインタフェースを実現し、2つのオブジェクトが関係していないことを示しているが、反復器が欠けているのは、次の要素があるかどうか、および次の要素が何なのかなどの関係を判断する必要があるため、foreach遍歴に時間がかかる原因である.同様に、オブジェクト間に関係がある場合、すなわち、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();
	}