2016-10-26 10 views
0

새로운 별도의 작업을 만들 때 LINQ 쿼리 .asparallel를 실행하는 데 걸리는, 나는 .AsParallel을 사용했다 : 그런 다음증가는 시간에 C#을 LINQ 쿼리에서

var completeReservationItems = from rBase in reservation.AsParallel() 
             join rRel in relationship.AsParallel() on rBase.GroupCode equals rRel.SourceGroupCode 
             join rTarget in reservation.AsParallel() on rRel.TargetCode equals rTarget.GroupCode 
             where rRel.ProgramCode == programCode && rBase.StartDate <= rTarget.StartDate && rBase.EndDate >= rTarget.EndDate 
             select new Object 
             { 
              //Initialize based on the query 
             }; 

, 나는 두 개의 별도의 작업을 생성했다있다 두 방식에 동일한리스트를 전달 병렬로 실행하는 것은 다음과 같이

  Task getS1Status = Task.Factory.StartNew(
      () => 
      { 
       RunLinqQuery(params); 
      }); 
     Task getS2Status = Task.Factory.StartNew(
      () => 
      { 
       RunLinqQuery(params); 
      }); 

     Task.WaitAll(getS1Status, getS2Status); 

I의 타이밍을 포착하고 다음 타이밍이었다고보고 놀랐다 하였다

  1. 위 시나리오 : 6 초 (6000 밀리 초)
  2. 같은 코드 대신이 작업을 순차적으로 실행 : 50 밀리
  3. 같은 코드를하지만, LINQ의 .AsParallel()하지 않고 : 50 밀리

위 시나리오에서 왜 이렇게 오래 걸리는지 이해하고 싶었습니다.

+2

병렬이 더 빠르다는 것을 의미하지는 않습니다.parralelism을 사용하면 기본 작업이 빠르면 스레드 간의 컨텍스트 전환에 너무 많은 시간이 걸리기 때문에 작업 속도가 느려집니다. – tym32167

+0

@ tym32167 합의했지만이 시나리오에서 스레드가 어떤 방식으로 생성되는지 알고 싶었습니다. 언급 한 시나리오 2와 3에서 여전히 병렬 작업이 될 것이기 때문에 더 빠릅니다. –

답변

1

답변을 게시하려면 표시 할 코드가 있어야합니다.

우선, 얼마나 많은 스레드가 AsParallel()으로 만들어 질지는 알 수 없습니다. 문서는 그것에 대해 아무 말도 해달라고 https://msdn.microsoft.com/en-us/library/dd413237(v=vs.110).aspx

우리가 볼 얼마나 많은 스레드의 식별자 코드

void RunMe() 
{ 
    foreach (var threadId in Enumerable.Range(0, 100) 
          .AsParallel() 
          .Select(x => Thread.CurrentThread.ManagedThreadId) 
          .Distinct()) 
     Console.WriteLine(threadId); 
} 

다음과 같은 상상?

27 // several threads 
13 
38 
10 
43 
30 

는 생각, 스레드 수는 현재 스케줄러의 의존

30 // only one thread! 

다음 시간 : 나를 위해 때마다 스레드의 다른 수, 예를 들어 출력이 표시됩니다. 우리는 항상 WithDegreeOfParallelism (https://msdn.microsoft.com/en-us/library/dd383719(v=vs.110).aspx) 방법, 예를

void RunMe() 
{ 
    foreach (var threadId in Enumerable.Range(0, 100) 
          .AsParallel() 
          .WithDegreeOfParallelism(2) 
          .Select(x => Thread.CurrentThread.ManagedThreadId) 
          .Distinct()) 
     Console.WriteLine(threadId); 
} 

지금, 출력 의지가 최대 2 개 스레드를 포함를 호출하여 스레드의 최대 수를 정의 할 수 있습니다.

7 
40 

왜 중요합니까? 앞에서 말했듯이 스레드의 수는 성능에 직접적인 영향을 줄 수 있습니다. 그러나 이것은 모든 문제가 아닙니다. 귀하의 1 시나리오에서 스레드 풀 내부에서 수행하고 추가 오버 헤드를 추가 할 수있는 새로운 작업을 작성한 다음 Task.WaitAll이라고 부릅니다. 그것의 https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,72b6b3fa5eb35695에 대한 소스 코드를 봐, 확실 그 그 for 작업에 의해 추가 오버 헤드가 추가됩니다, 그리고 상황에서 AsParallel 첫 번째 작업 내에서 너무 많은 스레드를 취할 것입니다, 다음 작업은 continiously 시작할 수 있습니다. 더욱이, 이런 일이 발생할 수 있습니다. 따라서 1 시나리오를 1000 번 실행하면 아마도 매우 다른 결과를 얻게 될 것입니다.

그래서 마지막 인자는 병렬 코드를 측정하려고 시도하지만 올바른 방법은 매우 어렵습니다. 당신이 할 수있는만큼 병렬 자료를 사용하지 않는 것이 좋습니다. 성능 저하를 일으킬 수 있기 때문입니다. 정확히 알지 못하면 무엇을하고 있습니까?