2012-08-24 7 views
0

오늘 Linq 및 PLinq querys의 성능 영향을 테스트했습니다. 따라서 나는 msdn How to: Measure PLINQ Query Performance에 기사를 사용했습니다.성능 Linq

void Main() 
{ 
     var source = Enumerable.Range(0, 600000000); 
     System.Diagnostics.Stopwatch sw;  

     var queryToMeasure1 = from num in source 
          where num % 3 == 0 
          select Math.Sqrt(num); 

     var queryToMeasure2 = from num in source.AsParallel() 
          where num % 3 == 0 
          select Math.Sqrt(num);       

     long freq = Stopwatch.Frequency; 
     Console.WriteLine("Timer frequency in ticks per second = {0}", freq); 

     Console.WriteLine("Measuring 1"); 
     sw = System.Diagnostics.Stopwatch.StartNew(); 
     foreach (var n in queryToMeasure1) { } 
     Console.WriteLine("Total ticks: {0} - Elapsed time: {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds);  

     Console.WriteLine("Measuring 2"); 
     sw = System.Diagnostics.Stopwatch.StartNew(); 
     foreach (var n in queryToMeasure2) { } 
     Console.WriteLine("Total ticks: {0} - Elapsed time: {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds); 

     Console.WriteLine("Measuring 3"); 
     sw = System.Diagnostics.Stopwatch.StartNew();   
     System.Threading.Tasks.Parallel.ForEach(queryToMeasure1, n => {});   
     Console.WriteLine("Total ticks: {0} - Elapsed time: {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds); 

     Console.WriteLine("Measuring 4"); 
     sw = System.Diagnostics.Stopwatch.StartNew();   
     System.Threading.Tasks.Parallel.ForEach(queryToMeasure2, n => {});  
     Console.WriteLine("Total ticks: {0} - Elapsed time: {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds); 

     Console.WriteLine("Measuring 5"); 
     sw = System.Diagnostics.Stopwatch.StartNew(); 
     queryToMeasure2.ForAll(n => {});  
     Console.WriteLine("Total ticks: {0} - Elapsed time: {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds);); 
} 

테스트 환경 : Win7에 기업, 64 비트 8GB의 RAM, I7-2600 (8cores)에 LinqPad4는

나는 파악하고, 설명 할 수없는 이유를 하나 개의 코어 (측정 1)에서 쿼리 병렬 쿼리보다 빠릅니다. 병렬 작업의 이점을 얻으려면 일부 대리인을 추가해야합니까?

하지만 지금 결과 :

1.Run :

Timer frequency in ticks per second = 3312851 
Measuring 1 
Total ticks: 3525 - Elapsed time: 1 ms 
Measuring 2 
Total ticks: 15802 - Elapsed time: 4 ms 
Measuring 3 
Total ticks: 5940 - Elapsed time: 1 ms 
Measuring 4 
Total ticks: 26862 - Elapsed time: 8 ms 
Measuring 5 
Total ticks: 4387 - Elapsed time: 1 ms 

2.Run : 60000의 열거 가능한 범위

Timer frequency in ticks per second = 3312851 
Measuring 1 
Total ticks: 29740243 - Elapsed time: 8977 ms 
Measuring 2 
Total ticks: 33722438 - Elapsed time: 10179 ms 
Measuring 3 
Total ticks: 77145502 - Elapsed time: 23286 ms 
Measuring 4 
Total ticks: 120078284 - Elapsed time: 36246 ms 
Measuring 5 
Total ticks: 30899585 - Elapsed time: 9327 ms 

흥미로운에게 : 600,000,000의 열거 범위 사실 : 테스트 스크립트를 수행하기 전에 가비지 콜렉터를 사용하면 측정 4의 시간이 크게 증가합니다.

,515,

3.Run (LinqPad)에서 열거 가능한 600,000,000 범위 가비지 컬렉터 : 결론적

Timer frequency in ticks per second = 3312851 
Measuring 1 
Total ticks: 29597830 - Elapsed time: 8934 ms 
Measuring 2 
Total ticks: 33532083 - Elapsed time: 10121 ms 
Measuring 3 
Total ticks: 76403692 - Elapsed time: 23062 ms 
Measuring 4 
Total ticks: 58534548 - Elapsed time: 17668 ms 
Measuring 5 
Total ticks: 32943622 - Elapsed time: 9944 ms 

는, I는 방법 1 작은 선택 질의 및 방법 5 수행하는 최적의 선택이라고 말할 수있다 선택 대의원이 증가 할 것인가?

+3

Modulo와'Math.Sqrt'는 사소한 (너무 빠르기 때문에) PLINQ를위한 좋은 후보자가 아닙니다. 더 비싸면 좋습니다. http://msdn.microsoft.com/en-us/library/dd997399.aspx 또한 [내 질문은 여기]를 (http://stackoverflow.com/questions/7582591/how-to- plinq-an-existing-linq-with-joins), 필자는 추천할만한 수치를 나열했습니다. –

+1

실제 질문이 있으십니까? 아니면 토론을 시작하고 싶습니까? 그렇다면 "질문"은 적합하지 않습니다. – svick

+0

아니요. 토론을 시작하고 싶지 않습니다. 거대한 작업을 수행하는 가장 좋은 방법이 무엇인지 알고 싶습니다. 그리고 대의원들이 자격있는 성명을 발표하는 것이 싸다는 것은 확실하지 않았습니다. msdn에 따르면. 여기있는 사람들에 따르면, 그렇지 않습니다. – Florian

답변

1

계산이 매우 저렴합니다. 델리게이트 호출이 계산 자체보다 비싸기 때문에 비 병렬 LINQ를위한 훌륭한 후보는 아닙니다. PLINQ에는 작업 시작, 스레드간에 데이터 동기화 및 복사와 같은 추가 오버 헤드가 있습니다. 이것을 시도하십시오 :

bool Where(int i) { 
var sum = 0; 
for (10000 times) { 
    sum += i; 
} 
return i % 3 == 0; 
} 

그리고 where 절에서이 함수를 사용하십시오. 이 함수는 매우 비싸서 스레딩과 동기화에 따른 오버 헤드가 더 이상 실행 시간을 지배하지 않습니다.

기본적으로 PLINQ의 최악의 사용 사례를 측정하고 있습니다. 흥미로운 것을 측정 해보십시오.