2017-01-12 74 views
1

我有以下代码:懒惰评价并行查询

static IEnumerable<int> foo() 
{ 
    int den = 0; 
    yield return 10; 
    yield return 10; 
    yield return 10; 
    yield return 10/den; 
    yield return 10/den; 
} 
static public void Main() 
{ 
    foreach (var item in foo().AsParallel().Take(3)) 
    { 
     Console.WriteLine(item); 
    } 
    Console.ReadLine(); 
} 

此代码失败(因为采集的实际未使用的元素将被计算 - 计算PLINQ数据块)。 .Net是否支持真正的“懒惰”并行(没有使用未使用元素的块的预计算)?

注意:这只是一个简单的例子。据我所知,AsParallel应该用于大数据以避免开销。

+3

我错过了什么吗?你只需要改变顺序吧? 'foo()。拿(3).AsParallel()' – wdosanjos

+0

有什么区别? – LmTinyToon

+3

'AsParallel()'不知道后面会发生什么,所以它并行化了集合中的所有项目,从而导致了错误。 '采取(3).AsParallel()'采取前3个元素然后并行化他们,因此没有错误。 – wdosanjos

回答

1

如果你禁止块的预计算,那么你不能并行做任何工作。只有并行化任何流式运算符的方法是让它们查询数据源的更多项目,而不是确定它们需要并预先计算它们的值。如果你不能允许任何预先计算数据,那么按照定义,你不能对任何这些运算符进行任何并行处理,而只需要使用常规的LINQ操作而不是PLINQ。

+0

但是为什么plinq会处理额外的未使用的元素?为什么要预先计算额外的元素?我无法理解这个想法。我不明白为什么存储计算的块将以更好的性能并行发挥作用。 – LmTinyToon

+0

@LmTinyToon如果您只处理已询问的物品,那么*按照定义*您一次只处理一件物品,因为一次只需要处理一件物品。要处理多件物品的唯一可能方式是要求获得比尚未向您询问的物品更多的物品。 – Servy