AsParallel
Query expressions can be run in parallel. With the AsParallel
extension method, we enable parallel threads to improve performance.
We show a method that becomes twice as fast on a dual-core machine when AsParallel
is used. AsParallel
can make certain queries much faster.
We introduce 2 methods. The SumDefault()
method (shown first) sums all the elements in the array with the Sum method alone.
SumAsParallel
first calls AsParallel
on the array. It then calls Sum on the result of AsParallel
. The 2 methods have the same result.AsParallel
makes the query twice as fast. This is the result on a dual-core machine under light load.using System; using System.Diagnostics; using System.Linq; class Program { static int SumDefault(int[] array) { // Sum all numbers in the array. return array.Sum(); } static int SumAsParallel(int[] array) { // Enable parallelization and then sum. return array.AsParallel().Sum(); } static void Main() { // Generate array. int[] array = Enumerable.Range(0, short.MaxValue).ToArray(); // Test methods. Console.WriteLine(SumAsParallel(array)); Console.WriteLine(SumDefault(array)); const int m = 10000; var s1 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { SumDefault(array); } s1.Stop(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { SumAsParallel(array); } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns")); } }536821761 536821761 232450.53 ns 118515.85 ns
AsParallel
will not have great results on all kinds of queries. For small collections, AsParallel
will be slower because of the extra method call.
Enumerable.Range
(0, 2).AsParallel
makes the query run over 200 times slower instead of two times faster.1 1 48.84 ns 10914.27 ns
This program uses a static
field in a Func
implementation. It uses this Func
in a parallel query (created by AsParallel()
). The program is supposed to count the even numbers in the int
array.
AsParallel
call causes multiple threads to access the static
field. The threads use IsEvenCounter
, a non-thread-safe method.AsParallel()
call from the statement, the result is always 500.AsParallel
is creating multiple threads. And this exposes an error in the program design.using System; using System.Linq; class Program { static int _counter; static bool IsEvenCounter(int value) { // ... Return whether counter field is even. return Program._counter++ % 2 == 0; } static void Main() { Func<int, bool> func = Program.IsEvenCounter; int[] array = Enumerable.Range(0, 1000).ToArray(); // ... Use parallel query ten times on the array. // ... Write number of results matched by Func. for (int i = 0; i < 10; i++) { var result = array.AsParallel().Where(func); Console.WriteLine(result.Count()); } } }517 514 500 509 500 478 500 508 500 501
It is tempting to think that AsParallel
makes queries faster. This is true on certain, long-running queries, but it makes small and fast queries many times slower.