2012-02-20 3 views
5

다음 스 니펫이 예상 된 결과를 제공하지 않는 이유가 궁금합니다. 너무 작지 않은 무작위 배열을 정렬하고 3 가지 다른 방법을 사용합니다. 나는 그래서 나올 속도를 기다리고 있었다 :.NET 4.0의 Array.Sort()는 어떻게 되었습니까? TrySZSort()가 사라 졌습니까?

  1. 에 Array.sort() - 가장 빠른 네이티브 TrySZSort 기능을 사용하여 내가 사용자 지정 비교 자 클래스
  2. 를 사용하여 정렬을 내림차순 .NET 2.0
  3. 에서 기억으로
  4. 람다 식 정렬입니다.

강령 :

ascending took: 514 ms 
descending took: 537 ms 
desc lambda took: 915 ms 
ascending took: 511 ms 
descending took: 492 ms 
desc lambda took: 923 ms 
ascending took: 511 ms 
descending took: 483 ms 
desc lambda took: 912 ms 
ascending took: 511 ms 
descending took: 485 ms 
desc lambda took: 914 ms 
ascending took: 518 ms 
descending took: 485 ms 
desc lambda took: 924 ms 
... a.s.o. ... 

그래서, 람다 정말 느린입니다 :

class DescComparer : IComparer<double> { 
    // simple comparison 
    // (yes, its not exactly correct ...) 
    public int Compare(double x, double y) { 
     return (x > y) ? -1 : 1; 
    } 
} 
static void Main(string[] args) { 
    Stopwatch sw = new Stopwatch(); 
    Random rand = new Random(); 
    DescComparer comparer = new DescComparer(); 
    double[] a = new double[1000000]; 
    for (int r = 0; r < 20; r++) { 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort(a); 
     sw.Stop(); 
     Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, comparer); 
     sw.Stop(); 
     Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, (x,y) => -x.CompareTo(y)); 
     sw.Stop(); 
     Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds); 

    } 
    Console.Read(); 
} 

그러나 이상하게도, 다음과 같은 수 있습니다. 하지만 어떻게오고, 평범한 오름차순 Array.Sort는 더 이상 빠르지 않습니까? Array.Sort (T [], Comparer)가 개선되었거나 TrySZSort가 단순히 제거 되었기 때문에 그렇습니까? 또는 나는 무엇인가 놓쳤 느냐?

(출시 빌드, 디버그 없음, 반사판 사용 불가능, 지금 당장)) Thanks!

업데이트 :@@Reed Copsey의 힌트에 따르면 람다 식은 공정하지 않습니다. 나는 그것을 비교 자와 같은 것으로 바꾸려고했다. 속도가 빨라졌습니다. Asc/λ는 55 %에서 75 %로 증가했습니다. 그래서 그것은 여전히 ​​상당히 느립니다.

+1

을하지만, 반사보고에서, TrySZSort 사라되지 않으며, 정렬'모두'Sort' 및 호출됩니다 '메소드와 같지만 comparer이 널 (null)이거나 디폴트 값일 때만 호출됩니다. –

+0

@ Meta-Knight hm. 재미있는! 그래서 그것이 나타납니다, 관리 측면 조금 붙잡아. 말씀해 주셔서 감사합니다! –

+1

네, Array.Sort()는 .NET 4.에서 재 작성되었습니다. 여러 분류기가 있습니다.비교자가 잘못했을 때 무한 루프에 갇히지 않을 수도 있습니다. 참조 소스에서 사용할 수있는 주석 처리 된 소스 코드를보고 추격하십시오. –

답변

5

그래서 람다는 실제로 가장 느립니다. 하지만 어떻게오고, 평범한 오름차순 Array.Sort는 더 이상 빠르지 않습니까? Array.Sort (T [], Comparer)가 개선되었거나 TrySZSort가 단순히 제거 되었기 때문에 그렇습니까? 또는 나는 무엇인가 놓쳤 느냐?

글쎄, 여기에는 두 가지 문제가 있습니다. 첫째, 정말 빌드 및 시스템에 따라 달라집니다 - Array.Sort()이 중요한만큼, 가장 빠른이며, 64 년, 내 시스템에

:

86에
ascending took: 192 ms 
descending took: 248 ms 
desc lambda took: 326 ms 
ascending took: 194 ms 
descending took: 247 ms 
desc lambda took: 326 ms 

상황이 약간 다릅니다 -하지만

ascending took: 235 ms 
descending took: 223 ms 
desc lambda took: 325 ms 
ascending took: 234 ms 
descending took: 222 ms 
desc lambda took: 325 ms 

이러한 타이밍을 실행할 때 시각적 스튜디오 호스트를 연결 했습니까? VS 내에서 실행하면 릴리스 빌드조차도 매우 느려집니다 (즉, 기본적으로 Ctrl + F5 대신 F5).


또한 테스트가 람다와 관련하여 완전히 공정하지 못합니다. 당신은 것입니다 테스트를위한 동일한 메커니즘 사용한다 : 나는 성능 결과를 설명 할 수 없다

Array.Sort<double>(a, (x, y) => (x > y) ? -1 : 1); 
+0

오른쪽. 람다 (X86)와의 차이는 덜 중요합니다. 그러나 람다가없는 속도/오름차순 비율은 거의 동일합니다 : 5 %. –