Mat*_*ero 10 c# linq task-parallel-library
假设我有这两种方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
以下是我得到的结果:
PFactorial(25000) -> 0,9897 seconds
Factorial(25000) -> 0,9252 seconds
Run Code Online (Sandbox Code Playgroud)
我知道PLINQ由于线程设置而有一些开销,但是如此大的n我期待PLINQ更快.
这是另一个结果:
PFactorial(50000) -> 4,91035 seconds
Factorial(50000) -> 4,40056 seconds
Run Code Online (Sandbox Code Playgroud)
M.k*_*ary 10
聚合不可能实现并行.至少我无法想象在我的脑海里.无论如何,您应该通过将列表分成块来实现并行化.找到那些结果.最后成倍增加块.这是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;
}
Run Code Online (Sandbox Code Playgroud)
测试
PFactorial(50000) -> 1,41 seconds
Factorial(50000) -> 2,69 seconds
Run Code Online (Sandbox Code Playgroud)
编辑:正如Servy和Chatzigiannakis所提到的,如果你不使用种子它可以完美地使用并行化,你得到与上面相同的结果(更快一点).
return Enumerable.Range(1,n).Select(x => (BigInteger)x).AsParallel().Aggregate(BigInteger.Multiply);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
552 次 |
| 最近记录: |