有人能告诉我Plinq的正确代码是什么吗?我将双数组中每个元素的正弦的绝对值的平方根加起来,但是Plinq给出了错误的结果。
该计划的输出是:
Linq aggregate = 75.8310477905274(正确) Plinq聚合= 38.0263653589291(大约应该是它的一半)
我一定做错了什么,但我找不到什么......
(我在Core 2 Duo Windows 7 x64 PC上运行Visual Studio 2008。)
以下是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
double[] array = new double[100];
for (int i = 0; i < array.Length; ++i)
{
array[i] = i;
}
double sum1 = array.Aggregate((total, current) => total + Math.Sqrt(Math.Abs(Math.Sin(current))));
Console.WriteLine("Linq aggregate = " + sum1);
IParallelEnumerable<double> parray = array.AsParallel<double>();
double sum2 = parray.Aggregate((total, current) => total + Math.Sqrt(Math.Abs(Math.Sin(current))));
Console.WriteLine("Plinq aggregate = " + sum2);
}
}
}
答案 0 :(得分:3)
汇总在PLINQ中的工作方式略有不同。
而不是期望值 初始化累加器, 用户给我们一个工厂功能 生成值:
public static double Average(this IEnumerable<int> source)
{
return source.AsParallel().Aggregate(
() => new double[2],
(acc, elem) => { acc[0] += elem; acc[1]++; return acc; },
(acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; },
acc => acc[0] / acc[1]);
}
现在,PLINQ可以初始化一个 每个独立的累加器 线。现在每个线程都得到了它 自己的累加器,都折叠 功能和累加器组合 函数可以自由改变 蓄电池。 PLINQ保证 不会访问累加器 同时来自多个线程。
因此,在您的情况下,您还需要传递一个累加器函数,该函数对并行聚合的输出求和(因此您看到的结果大约是它应该的一半)。
答案 1 :(得分:0)
谢谢你的MSDN博客。它现在似乎正常工作。我改变了我的代码如下:
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Test();
}
static void Test()
{
double[] array = new double[100];
for (int i = 0; i < array.Length; ++i)
{
array[i] = i;
}
double sum1 = array.Aggregate((total, current) => total + Math.Sqrt(Math.Abs(Math.Sin(current))));
Console.WriteLine("Linq aggregate = " + sum1);
IParallelEnumerable<double> parray = array.AsParallel();
double sum2 = parray.Aggregate
(
0.0,
(total1, current1) => total1 + Math.Sqrt(Math.Abs(Math.Sin(current1))),
(total2, current2) => total2 + current2,
acc => acc
);
Console.WriteLine("Plinq aggregate = " + sum2);
}
}
}