首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并行聚合集

并行聚合集
EN

Stack Overflow用户
提问于 2015-11-09 16:01:33
回答 3查看 3.1K关注 0票数 3

我已经看到了基本类型的并行聚合代码。

代码语言:javascript
复制
Parallel.For<int>(0, result.Count, () => 0, (i, loop, subtotal) =>
    {
        subtotal += result[i];
        return subtotal;
    },
    (x) => Interlocked.Add(ref sum, x)
);

我想知道是否有类似的列表/其他集合,例如:

代码语言:javascript
复制
List<Result> AllResults;
Parallel.ForEach(allIDs, (currentID) =>
{

    subList.add(GetResultFor(currentID));
    return subList;
},
(x) =>
{
    lock(AllResults)
        AllResults.AddRange(subList);
};

我猜没有那么好和整洁,但我想不出另一种方法,当然不是通过一个标准的parralel.ForEach,因为我想不出你怎么会说“这个核心有这个范围,这个核心这个范围”.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-09 16:19:37

我认为在这两个示例中,https://msdn.microsoft.com/en-us/library/dd460688(v=vs.110).aspx可以为您提供更好的服务,并且在使用非线程安全集合时不需要手动锁定。

您的总和计算可转换为:

代码语言:javascript
复制
var sum = result.AsParallel().Sum();

使用List<T>的第二个示例可以转换为:

代码语言:javascript
复制
List<Result> results = allIDs.AsParallel()
                             .Select(id => GetResultFor(id))
                             .ToList();

注意,并行性只与测试结果一样好。并不是每次并行都会加速您的代码,有时它甚至会降低连续循环的性能。

票数 5
EN

Stack Overflow用户

发布于 2015-11-09 16:15:56

代码语言:javascript
复制
List<Result> AllResults = new List<Result>();

Parallel.ForEach(allIDs, () => new List<Result>(), (id, loopState, subList) =>
{
   subList.Add(GetResultFor(id));
   return subList;
},
subList => 
{ 
     lock(AllResults)
         AllResults.AddRange(subList); 
});
票数 1
EN

Stack Overflow用户

发布于 2015-11-09 16:35:21

代码语言:javascript
复制
    var nums = Enumerable.Range(0, 1000000000);
    var parallel = nums.AsParallel();
    var mapped = parallel.Select(x => (long) unchecked( x * x)); 
    var sum = mapped.Sum();

    Console.WriteLine(sum);

映射(选择)总是可以并行进行的.减缩(和)太“有点”.您可以使用许多工作线程来对所有不同的和进行求和,直到剩下“最后”和为止。通常情况下,(90%)对所有事物进行同步求和会得到最好的结果。

另一个例子是select many:

代码语言:javascript
复制
        IList<IEnumerable<long>> manyNumbers = new List<IEnumerable<long>>();
        for (int i = 0; i < 16; i+=2)
        {
            manyNumbers.Add(Enumerable.Range(2 << i, 2 << (i + 1)).AsParallel().Select(a=> (long)a));
        }
        var parallel = manyNumbers.AsParallel();

        var allPrimes = parallel.SelectMany(sumNums =>
        {
            IEnumerable<long> somePrimes= sumNums.Where(num =>
           {
               for (long i = 2; i <= Math.Sqrt(num); i++)
               {
                   if (num % i == 0)
                   {
                       return false;
                   }
               }
               return true;
           }
            );
            return somePrimes;
        }

        );

        foreach (var number in allPrimes)
        {
            Console.WriteLine(number);
        }

        long sumOfPrimes = allPrimes.Sum();


        Console.WriteLine(sumOfPrimes);
        Console.ReadLine();

这不是一个很好的算法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33613163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档