将IEnumerable <t>转换为具有一个并行度的ParallelQuery <t>有哪些下游副作用?

时间:2017-04-29 21:35:58

标签: c# .net linq extension-methods plinq

使用一种并行度将IEnumerable<T>转换为ParallelQuery<T>的下游成本是多少?

例如:

Enumerable.Range(0, 1000)
          .Where(x => x <= target)
          .Select(x => x + 5); 

Enumerable.Range(0, 1000)
          .AsParallel()
          .WithDegreeOfParallelism(1)
          .Where(x => x <= target)
          .Select(x => x + 5);

从参考资料中可以清楚地看出会有一些开销(例如将IEnumerable<T>包裹在ParallelEnumerableWrapper中)。

来自ParallelEnumerable.cs

public static ParallelQuery AsParallel(this IEnumerable source)
{
    if (source == null) throw new ArgumentNullException(nameof(source));

    return new ParallelEnumerableWrapper(source);
}

public static ParallelQuery<TSource> WithDegreeOfParallelism<TSource>(this ParallelQuery<TSource> source, int degreeOfParallelism)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (degreeOfParallelism < 1 || degreeOfParallelism > Scheduling.MAX_SUPPORTED_DOP)
    {
        throw new ArgumentOutOfRangeException(nameof(degreeOfParallelism));
    }

    QuerySettings settings = QuerySettings.Empty;
    settings.DegreeOfParallelism = degreeOfParallelism;

    return new QueryExecutionOption<TSource>(
        QueryOperator<TSource>.AsQueryOperator(source), settings);
}

试验:

如果传递给扩展方法的degreeOfParallelism大于1,则行为符合预期。

degreeOfParallelism等于1的测试中,行为看起来像,就像顺序实现一样。然而,我还没能在野外找到这种模式的例子。

假设:

  • 拨打AsParallelWithDegreeOfParallelism所产生的开销是可以接受的。
  • 枚举源集合不会引入副作用。
  • 所有后续操作都会延迟执行,不会引入副作用。
  • 有一个(非不合理的)业务案例,更喜欢IEnumerable<T>上的单个扩展方法,并行可选参数,用于顺序和并行实现的单独扩展方法。 / LI>

问题:

  1. 此模式是否会为后续方法调用引入下游成本?
  2. 如果是这样,这些费用是否可以预测?

0 个答案:

没有答案