2016-10-23 2 views
3

Вопрос

В запросе LINQ я могу правильно (например: компилятор не будет жаловаться) вызов .AsParallel(), как это:Куда звонить .AsParallel() в запросе LINQ

(from l in list.AsParallel() where <some_clause> select l).ToList(); 

или как это:

(from l in list where <some_clause> select l).AsParallel().ToList(); 

что именно разница?

То, что я пытался

Судя по official documentation я почти всегда видел первый метод, используемый таким образом, я думал, что был путь.
Сегодня, я попытался запустить некоторый тест самостоятельно, и результат был неожиданным. Вот код, я бежать:

var list = new List<int>(); 
var rand = new Random(); 
for (int i = 0; i < 100000; i++) 
    list.Add(rand.Next()); 

var treshold= 1497234; 

var sw = new Stopwatch(); 

sw.Restart(); 
var result = (from l in list.AsParallel() where l > treshold select l).ToList(); 
sw.Stop(); 

Console.WriteLine($"call .AsParallel() before: {sw.ElapsedMilliseconds}"); 

sw.Restart(); 
result = (from l in list where l > treshold select l).AsParallel().ToList(); 
sw.Stop(); 

Console.WriteLine($"call .AsParallel() after: {sw.ElapsedMilliseconds}"); 

Выход

вызов .AsParallel() до: 49
.AsParallel вызова() после того, как: 4

Итак, очевидно, несмотря на то, что говорит документация, второй способ намного быстрее. Что здесь происходит?

+0

Ваша машина одноядерная или многоядерная? –

+0

@viveknuna multi-core – Mahatma

+0

Он даст вам разные результаты каждый раз –

ответ

5

Трюк с использованием AsParallel в целом заключается в том, чтобы решить, насколько экономия от параллелизма перевешивает накладные расходы на параллельные операции.

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

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

Для примера сложного жесткого состояния рассмотрим метод, который определяет, является ли число простым или нет. Выполнение этого параллельно на многоядерном процессоре продемонстрирует значительное улучшение по сравнению с непараллелизированной реализацией.

+0

спасибо за ваш ответ, но я до сих пор не совсем понимаю разницу между двумя вызовами. Вы имеете в виду это, когда я вызываю .AsParallel() вторым способом (в конце запроса), я на самом деле ничего не распараллеливаю? – Mahatma

+1

@ Махатма Да, к тому времени работа уже выполнена в последовательном режиме. Все потребности LINQ - собирать результаты из параллельных потоков в один список. – dasblinkenlight

+0

Я вижу сейчас, большое спасибо. – Mahatma

Смежные вопросы