2009-11-28 3 views
6

Это не похоже на приседания для следующей тестовой программы. Это потому, что я тестирую небольшой список?Как работает AsParallel?

static void Main(string[] args) 
{ 
    List<int> list = 0.UpTo(4); 

    Test(list.AsParallel()); 
    Test(list); 
} 

private static void Test(IEnumerable<int> input) 
{ 
    var timer = new Stopwatch(); 
    timer.Start(); 
    var size = input.Count(); 
    if (input.Where(IsOdd).Count() != size/2) 
     throw new Exception("Failed to count the odds"); 

    timer.Stop(); 
    Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
} 

private static bool IsOdd(int n) 
{ 
    Thread.Sleep(1000); 
    return n%2 == 1; 
} 

Обе версии рассчитаны на 4 секунды.

+2

Как вы получили метод Upto, метод расширения? – thewpfguy

ответ

23

Задача Параллельная библиотека заботится о статического типа последовательности. Он должен быть IParallelEnumerable<T> для операций, выполняемых TPL. Вы вызываете коллекцию обратно в IEnumerable<T>, когда вы звоните Test. Следовательно, компилятор разрешит .Where вызов последовательности в System.Linq.Enumerable.Where метод расширения вместо параллельной версии, предоставляемой TPL.

1

Как работает Параллель, помещая ваши вещи в ThreadPool. Кроме того, сколько ядер у вас есть? Если вы работаете на одной основной машине, которая все равно займет около 4 секунд.

5

(Обновление для .NET4, так как этот вопрос занимает довольно высоко в поиске Google для AsParallel())

Просто несколько изменений позволят вашему примеру работать, как я полагаю, вы ожидали.

Изменение List<int> list = 0.UpTo(4); в var list = Enumerable.Range(0, 4);

Ваш пример будет работать, если вы добавили перегрузку функции с подписью, которая принимает ParallelQuery ...

private static void Test(ParallelQuery<int> input) 
    { 
     var timer = new Stopwatch(); 
     timer.Start(); 

     int size = input.Count(); 
     if (input.Where(IsOdd).Count() != size/2) 
     { 
      throw new Exception("Failed to count the odds"); 
     } 
     timer.Stop(); 

     Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
    } 

В качестве альтернативы, вы можете использовать синтаксис LINQ ....

private static void Test(ParallelQuery<int> list) 
    { 
     var timer = Stopwatch.StartNew(); 

     if ((from n in list.AsParallel() 
      where IsOdd(n) 
      select n).Count() != (list.Count()/2)) 
     { 
      throw new Exception("Failed to count the odds"); 
     } 

     Console.WriteLine("Tested " + list.Count() + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
    } 

Надеюсь, это поможет кому-то!