[편집 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에있는 권투를 볼 수 없습니다!
숫자 (1000 만 작업 당 틱)를 숫자에 넣으십시오. 그렇지 않으면 결과가 처리량 (초당 작업)과 쉽게 혼동됩니다. –
Release without VS에서 코드를 실행 한 적이 있습니까 (예 : cmd에서 exe를 실행). 결과는 그 결과에 따라 실제로 달라질 수 있습니다. 또한 코드를 디 컴파일하고 일리노이를 살펴보아야합니다. (또는 사람들이 직접 할 수 없도록 게시물에 붙여 넣으십시오) 실제로 진행되고있는 것에 대한 정보가 있어야합니다. – Sehnsucht
디버거없이 릴리스 테스트 첨부 된 한 가지 문제는 목록의 개수에 대한 배열의 루프를 검사하는 범위에 있다는 것입니다. JITs가 경계 검사를 생략하고 프로세서 캐시를 지우는 기능을 휴지통으로 옮길 것이라고 확신합니다. –