【问题标题】:Lazy evaluation in parallel queries并行查询中的延迟评估
【发布时间】:2017-01-12 14:35:24
【问题描述】:

我有以下代码:

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 应该用于大数据以避免开销。

【问题讨论】:

  • 我错过了什么吗?您只需要更改顺序,对吗? foo().Take(3).AsParallel()
  • 有什么区别?
  • AsParallel() 不知道后面会发生什么,因此它并行化了集合中的所有项目,因此出现了错误。 Take(3).AsParallel() 采用前 3 个元素,然后将它们并行化,因此没有错误。
  • @wdosanjos,据我了解,在您的情况下,结果收集不会以并行方式处理
  • 如果AsParallel 是最后一个操作,那么结果类型将为ParallelEnumerableWrapper,它只给出简单的顺序枚举数

标签: c# .net linq parallel-processing plinq


【解决方案1】:

如果您禁止对块进行预计算,那么您将无法并行执行任何工作。 唯一 并行化任何流式操作符的方法是让他们查询数据源的更多项,而不是他们可以确定他们需要并预先计算它们的值。如果您不能允许对数据进行任何预计算,那么根据定义,您就不能对这些运算符中的任何一个并行执行任何处理,而只需要使用常规 LINQ 操作而不是 PLINQ。

【讨论】:

  • 但是为什么 plinq 会处理多余的未使用元素?为什么它预先计算额外的元素?我无法理解这个想法。我不明白为什么存储计算块会以并行方式提供更好的性能。
  • @LmTinyToon 如果您只处理被要求的项目,那么根据定义您一次只能处理一个项目,因为一次只能处理一个项目时间总是被要求的。您可以处理多个项目的唯一可能方法是要求比尚未要求您的项目更多的项目。
猜你喜欢
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
相关资源
最近更新 更多