Information Technology Reference
In-Depth Information
called MoveNext
Delivered 290 at 1:50:39 PM
Notice how much it changed. The very first call to MoveNext() causes
PLINQ to start all the threads involved in generating the results. That
causes quite a few (in this case, almost all) result objects to be produced.
Each subsequent call to MoveNext() will grab the next item from those
already produced. You can't predict when a particular input element will
be processed. All you know is that the query will begin executing (on sev-
eral threads) as soon as you ask for the first element of the query.
PLINQ's methods that support query syntax understand how this behav-
ior can affect performance on queries. Suppose you modify the query to
select the second page of results using Skip() and Take():
var answers = ( from n in ParallelEnumerable .Range( 0 , 300 )
where n.SomeTest()
select n.SomeProjection()).
Skip( 20 ).Take( 20 );
Executing this query produces output that is identical to that produced by
LINQ to Objects. That's because PLINQ knows that it will be faster to pro-
duce only 20 elements rather than 300. (I'm simplifying, but PLINQ's
implementation of Skip() and Take() do tend to favor a sequential algo-
rithm more than other algorithms.)
Yo u c a n m o d i f y t h e q u e r y a b i t m o r e , a n d g e t P L I N Q t o g e n e r a t e a l l t h e
elements using the parallel execution model. Just add an orderby clause:
var answers = ( from n in ParallelEnumerable .Range( 0 , 300 )
where n.SomeTest()
orderby n.ToString().Length
select n.SomeProjection()).
Skip( 20 ).Take( 20 );
The lambda argument for orderby must not be something that the com-
piler can optimize away (that's why I used n.ToString().Length rather than
just n above). Now, the query engine must generate all the elements of the
output sequence before it can order them properly. Only once the elements
are ordered properly can the Skip() and Take() methods know which ele-
ments should be returned. Of course, it's faster on multicore machines to
use multiple threads to generate all the output than it would be to gener-
ate the sequence sequentially. PLINQ knows that, too, so it starts multiple
threads to create the output.
 
Search WWH ::




Custom Search