2010-04-21 2 views
1

UsingAs 및 UsingCast의 순서를 바꿀 때 성능이 서로 바뀌는이 코드가 있습니다.벤치마킹 할 때 캐시를 무효화하는 방법은 무엇입니까?

using System; 
using System.Diagnostics; 
using System.Linq; 

using System.IO; 

class Test 
{ 
    const int Size = 30000000; 

    static void Main() 
    { 
     object[] values = new MemoryStream[Size]; 



     UsingAs(values); 
     UsingCast(values); 


     Console.ReadLine(); 
    } 

    static void UsingCast(object[] values) 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 
     int sum = 0; 
     foreach (object o in values) 
     { 
      if (o is MemoryStream) 
      { 
       var m = (MemoryStream)o; 
       sum += (int)m.Length; 
      } 
     } 
     sw.Stop(); 
     Console.WriteLine("Cast: {0} : {1}", sum, 
          (long)sw.ElapsedMilliseconds); 
    } 

    static void UsingAs(object[] values) 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 
     int sum = 0; 
     foreach (object o in values) 
     { 

      if (o is MemoryStream) 
      { 
       var m = o as MemoryStream; 
       sum += (int)m.Length; 
      } 
     } 
     sw.Stop(); 
     Console.WriteLine("As: {0} : {1}", sum, 
          (long)sw.ElapsedMilliseconds); 
    } 


} 

출력이에

As: 0 : 322 
Cast: 0 : 281 

이 일을 ...

UsingCast(values); 
UsingAs(values); 

... 결과 :

Cast: 0 : 322 
As: 0 : 281 

바로이 일을 ...

이에
UsingAs(values); 

... 결과 :

As: 0 : 322 

이 일을 그냥이에

UsingCast(values); 

... 결과를 실행에서 제외

Cast: 0 : 322 

독립적으로, 방법 캐시를 무효화하십시오. 벤치 마크되는 두 번째 코드는 첫 번째 코드의 캐시 된 메모리를받지 못합니까?

벤치마킹은 제쳐 놓고, 바로 현대의 프로세서 :-)이 캐싱 마술을 할 수 있다는 사실을 사랑

[편집]이 빠른 코드를 (아마도) 시도하는 것이 좋습니다으로

...

As and null test: 0 : 342 
,691,363 :
static void UsingAsAndNullTest(object[] values) 
{   
    Stopwatch sw = Stopwatch.StartNew(); 
    int sum = 0; 
    foreach (object o in values) 
    { 
     var m = o as MemoryStream; 
     if (m != null) 
     {     
      sum += (int)m.Length; 
     } 
    } 
    sw.Stop(); 
    Console.WriteLine("As and null test: {0} : {1}", sum, 
         (long)sw.ElapsedMilliseconds); 
} 

... 결과는 이것이다 각 루틴 자신의 복사본을 손에 조언으로

...

static void UsingAs(object[] values) 
{ 
    object[] a = values.ToArray(); 

    Stopwatch sw = Stopwatch.StartNew(); 
    int sum = 0; 
    foreach (object o in a) 
    { 

     if (o is MemoryStream) 
     { 
      var m = o as MemoryStream; 
      sum += (int)m.Length; 
     } 
    } 
    sw.Stop(); 
    Console.WriteLine("As: {0} : {1}", sum, 
         (long)sw.ElapsedMilliseconds); 
} 

static void UsingCast(object[] values) 
{ 
    object[] a = values.ToArray(); 

    Stopwatch sw = Stopwatch.StartNew(); 
    int sum = 0; 
    foreach (object o in a) 
    { 
     if (o is MemoryStream) 
     { 
      var m = (MemoryStream)o; 
      sum += (int)m.Length; 
     } 
    } 
    sw.Stop(); 
    Console.WriteLine("Cast: {0} : {1}", sum, 
         (long)sw.ElapsedMilliseconds); 
} 

... 출력 :

Cast: 0 : 282 
As: 0 : 282 

[편집] 위의 두 코드210

느린

이제는 동일한 결과를 얻었습니다. Remus!

캐스팅 실행 중 및 독립 실행 형에서도 같은 결과 (예 : 282)가 나타납니다. 자, 그들이 (322에서 282 밀리 초)까지 배열의 사본을 나눠준 이유는 무엇입니까? - 그건 완전히 다른 이야기입니다 :-) 그건 완전히 다른 이야기입니다.

+0

가장 빠른 방법은 'is'를 확인하지 않고 'as'연산자를 사용하고 '== null'에 대한 결과를 테스트하는 것입니다. –

+0

코드를 더 빠르게 만드는 방법에 대해 묻지 않습니다. 적절한 벤치마킹 방법을 묻습니다. 그리고 나는 누군가가 'as'를 사용하고'== null'을 테스트 할 것을 암시한다. (물론 누군가 가지고있다.) 슬프게도, 그 접근법은 위의 두 코드보다 느리다. –

답변

1

사진에서 벗어나고 싶다면 L2 캐쉬와 TLB가 빠진 다음 동일한 크기의 다른 MemoryStream에서 두 번째 테스트를 호출하면됩니다.