【问题标题】:What is the equivalent of Spliterator in C#?C# 中的 Spliterator 等价物是什么?
【发布时间】:2018-08-26 14:32:59
【问题描述】:

在 Java 中,我可以编写一个Spliterator 接口实现,我可以在其中指定源集合将如何精确地拆分为子集合以进行并行处理。

但是我不明白如何在C#中做到这一点,我只知道你可以在IEnumerable上调用AsParallel,但是你能控制拆分过程吗?

例如,我的源集合是一个数组,我想将其拆分为 5 个项子数组,并希望 linq 与这些子数组一起工作。这可能吗?

【问题讨论】:

    标签: c# .net linq spliterator


    【解决方案1】:

    如果您有特定的分区要求,您应该查看Custom Partitioners for PLINQ and TPLHow to: Implement a Partitioner for Static Partitioning。这些给出了如何实现Partitioner<TSource> 的示例,它可能类似于Java 的Spliterator

    但是,在大多数情况下,让框架选择自己的动态分区策略更有益。如果您的要求是将并发级别限制为5,您可以使用WithDegreeOfParallelism

    var summary = ints
        .AsParallel()
        .WithDegreeOfParallelism(5)
        .Aggregate(
            seed: (
                count: 0,
                sum: 0,
                min: int.MaxValue,
                max: int.MinValue),
            updateAccumulatorFunc: (acc, x) => (
                count: acc.count + 1,
                sum: acc.sum + x,
                min: Math.Min(acc.min, x),
                max: Math.Max(acc.max, x)),
            combineAccumulatorsFunc: (acc1, acc2) => (
                count: acc1.count + acc2.count,
                sum: acc1.sum + acc2.sum,
                min: Math.Min(acc1.min, acc2.min),
                max: Math.Max(acc1.max, acc2.max)),
            resultSelector: acc => (
                acc.count,
                acc.sum,
                acc.min,
                acc.max,
                avg: (double)acc.sum / acc.count));
    

    【讨论】:

    • 而且每个分区都会被单独的线程处理,对吧?
    • 每个分区可能由单独的线程处理。 TPL 和 PLINQ 在 .NET 线程池上运行,该线程池保持有限数量的线程(通常等于您机器中的逻辑内核数)。如果您的分区程序生成的分区多于线程池中的线程数,则某些分区将排队。这是正确的做法——如果线程数多于内核数,您将超额订阅处理器,从而降低效率。
    • 你不能指定线程池中的线程数多于核心数吗?在 Java 中,您可以创建一个执行程序实例并在构造函数中提供线程数。 docs.oracle.com/javase/7/docs/api/java/util/concurrent/…
    • 您可以增加线程数,包括使用ThreadPool.SetMinThreads 的默认线程池。但是,对于受 CPU 限制的工作,这样做通常不符合您的利益,因为您只会因上下文切换而导致效率低下。
    【解决方案2】:

    目前 C# 不像 Java 那样提供此功能。 C# 中的并行任务有一个 MaxDegreeOfParallelism 参数,可让您指定 ParallelOptions 实例启用的最大并发任务数,并自动处理任务数。

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 2023-03-30
      • 2010-09-17
      • 2011-07-26
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多