2016-08-09 4 views
-2

[편집 3 ...]int.CompareTo와의 성능 차이

가짜 : 테스트를 손상시킨 루프를 사용하는 원래 코드입니다. 아래의 코드를 보면 명백한 것처럼 보입니다. 결국 "거대한"차이가 아닙니다. 그냥 ...

int[] arr; 
int j, comp; 

comp = j.CompareTo(arr[j]); 
comp = arr[j].CompareTo(j); 

"동일한"비교의 버전을 반전 :

나는 원래 내가 compareTo와의이 두 가지 형태 사이의 성능에 큰 차이를 보았다고 생각! --- Array 대신 List를 사용하여 시도해 보았습니다.

내 원래 코드는 루프를 다르게로드하여 테스트에 문제가 발생했습니다. 조정 된 테스트는 아래와 같습니다. 내가 본 것 같았던 "커다란"차이점을 보여주지는 않습니다.

나는 또한 목록을 권투와 unboxing을 도입 믿었 ... 나는 IL 코드를 배우게됩니다.

첫 번째 쌍의 두 양식과 두 번째 쌍의 두 양식간에 여전히 약간의 차이가 있습니다. 이것은 코드가 매우 유사하지만 다른 IL 출력을 생성하므로 약간의 흥미가있을 수 있습니다. 스톱워치에서

는 내 컴퓨터에서 나는 얻을 틱 :

int.CompareTo(List<int>[]) (Unboxing?) 
337095 

List<int>[].CompareTo(int) (Boxing?) 
375601 

int.CompareTo(Array<int>[]) 
157093 

Array<int>[].CompareTo(int) 
135420 

새로운 코드 :

static void Main() { 
    Stopwatch stopwatch = new Stopwatch(); 
    int iterations = 100000000; 
    int comp = 0, accessIndex = 50, arg = 0; 
    List<int> list = new List<int>(100); 
    int[] arr = new int[100]; 
    for (int i = 0, j = 0; j < 100; i+=2, j++) { 
     list.Add(i); 
     arr[j] = i; 
    } 

    Console.WriteLine("int.CompareTo(List<int>[]) (Unboxing?)"); 
    stopwatch.Reset(); 
    stopwatch.Start(); 
    for (int i = 0; i < iterations; i++) { 
     comp = arg.CompareTo(list[accessIndex]); 
    } 
    stopwatch.Stop(); 
    Console.WriteLine(stopwatch.ElapsedTicks); 
    Console.WriteLine(); 

    Console.WriteLine("List<int>[].CompareTo(int) (Boxing?)"); 
    stopwatch.Reset(); 
    stopwatch.Start(); 
    for (int i = 0; i < iterations; i++) { 
     comp = list[accessIndex].CompareTo(arg); 
    } 
    stopwatch.Stop(); 
    Console.WriteLine(stopwatch.ElapsedTicks); 
    Console.WriteLine(); 

    Console.WriteLine("int.CompareTo(Array<int>[])"); 
    stopwatch.Reset(); 
    stopwatch.Start(); 
    for (int i = 0; i < iterations; i++) { 
     comp = arg.CompareTo(arr[accessIndex]); 
    } 
    stopwatch.Stop(); 
    Console.WriteLine(stopwatch.ElapsedTicks); 
    Console.WriteLine(); 

    Console.WriteLine("Array<int>[].CompareTo(int)"); 
    stopwatch.Reset(); 
    stopwatch.Start(); 
    for (int i = 0; i < iterations; i++) { 
     comp = arr[accessIndex].CompareTo(arg); 
    } 
    stopwatch.Stop(); 
    Console.WriteLine(stopwatch.ElapsedTicks); 
    Console.WriteLine(); 
} 

여전히 읽는 경우 다음과 마지막 쌍의 IL 코드의 차이 (어레이)만을 루프의 상부에있다 :

"int.CompareTo (배열 [])"==

0

는 "배열 [].은 compareTo (INT)"

// loop start (head: IL_0160) 
IL_014b: ldloc.s arr 
IL_014d: ldloc.3 
IL_014e: ldelema [mscorlib]System.Int32 
IL_0153: ldloc.2 
IL_0154: call instance int32 [mscorlib]System.Int32::CompareTo(int32) 

그리고 목록 버전 ==

, 나는 IL에있는 권투를 볼 수 없습니다!

+1

숫자 (1000 만 작업 당 틱)를 숫자에 넣으십시오. 그렇지 않으면 결과가 처리량 (초당 작업)과 쉽게 혼동됩니다. –

+2

Release without VS에서 코드를 실행 한 적이 있습니까 (예 : cmd에서 exe를 실행). 결과는 그 결과에 따라 실제로 달라질 수 있습니다. 또한 코드를 디 컴파일하고 일리노이를 살펴보아야합니다. (또는 사람들이 직접 할 수 없도록 게시물에 붙여 넣으십시오) 실제로 진행되고있는 것에 대한 정보가 있어야합니다. – Sehnsucht

+0

디버거없이 릴리스 테스트 첨부 된 한 가지 문제는 목록의 개수에 대한 배열의 루프를 검사하는 범위에 있다는 것입니다. JITs가 경계 검사를 생략하고 프로세서 캐시를 지우는 기능을 휴지통으로 옮길 것이라고 확신합니다. –

답변

-2

가짜!

내가 사용한 루프에서 내 원래 코드 테스트가 문제가되었습니다. 편집 된 코드는 꽤 일관된 결과를 보여줍니다 ... 그리고 일리노이는 분명해 보입니다.