c# – 为什么PLINQ比循环慢?
发布时间:2020-12-15 18:00:10 所属栏目:百科 来源:网络整理
导读:假设我有这两种方法: public BigInteger PFactorial(int n){ return Enumerable.Range(1,n) .AsParallel() .Select(i = (BigInteger)i) .Aggregate(BigInteger.One,BigInteger.Multiply);}public BigInteger Factorial(int n){ BigInteger result = BigInte
假设我有这两种方法:
public BigInteger PFactorial(int n) { return Enumerable.Range(1,n) .AsParallel() .Select(i => (BigInteger)i) .Aggregate(BigInteger.One,BigInteger.Multiply); } public BigInteger Factorial(int n) { BigInteger result = BigInteger.One; for(int i = 1; i <= n; i++) result *= i; return result; } 以下是我得到的结果: PFactorial(25000) -> 0,9897 seconds Factorial(25000) -> 0,9252 seconds 我明白PLINQ有一些开销,因为线程的设置,但有这么大的n我期待PLINQ更快. 这是另一个结果: PFactorial(50000) -> 4,91035 seconds Factorial(50000) -> 4,40056 seconds 解决方法
并行是不可能的聚合.至少我不能想像在我心中.无论如何,您应该将列表划分成块,从而实现并行化.找到这些结果.最后加倍块.这是PLinq的快速方式.
static public BigInteger PFactorial(int n) { var range = Enumerable.Range(1,n).Select(x => (BigInteger) x).AsParallel(); var lists = range.GroupBy(x => x/(n/Environment.ProcessorCount)).Select(x => x.AsEnumerable()); var results = lists.Select(x => x.Aggregate(BigInteger.One,BigInteger.Multiply)); var result = results.Aggregate(BigInteger.One,BigInteger.Multiply); return result; } 测试 PFactorial(50000) -> 1,41 seconds Factorial(50000) -> 2,69 seconds 编辑:如Servy和Chatzigiannakis所提到的,如果你不使用种子,它可以完美地使用并行化,并且得到与上述相同的结果(稍快一些). return Enumerable.Range(1,n).Select(x => (BigInteger)x).AsParallel().Aggregate(BigInteger.Multiply); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |