読み書き高品質コード整理(三)-性能
2618 ワード
まず、次のコードを使用します.
出力結果:
question:なぜ2つのサイクルの効率がこんなに悪いのですか.
私はjava菜鸟で、私はコードを书く时気持ちを见て、それを书くと思ってそれを书いて、効率があまり悪くないと思って、思いもよらなかった...うわっ、菜鳥がショック~
Apiを読んでからArrayListがRandomAccessインタフェース(ランダムアクセス)を実現していることがわかりました.これはシンボルインタフェースで、何の実現も必要ありません.
foreach方式はiterator(反復器)の変形用法であり、
反復器は23の設計モードの1つで、「提供中メソッドは、オブジェクトの内部の詳細を露出することなく、コンテナオブジェクトの各要素にアクセスします」と、反復器コンテナを作成し、内部の詳細を遮断する必要があります.しかし、ArrayListはRandomAccessインタフェースを実現し、2つのオブジェクトが関係していないことを示しているが、反復器が欠けているのは、次の要素があるかどうか、および次の要素が何なのかなどの関係を判断する必要があるため、foreach遍歴に時間がかかる原因である.同様に、オブジェクト間に関係がある場合、すなわち、LinkedListクラスのようなリスト実装クラスがランダムアクセスではなく、双方向チェーンテーブルであり、previous node-current node-next nodeである場合、foreach反復を使用する方が効率的である.興味のある方はLinkedListのapiをご覧ください.averageメソッドの再構築:
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();
}