对于阶乘(Parallel和Normal),答案并不相同

本文关键字:答案 于阶乘 阶乘 Parallel Normal | 更新日期: 2023-09-27 18:16:38

为什么跟帖的答案不一样?

正常编码:

long sum = 0;
for (long i = 1; i <= 10; i++)
{
    long result = 1;
    for (long j = 1; j <= i; j++)
    {
        result = result*j;
    }
    sum = sum + result;
}
并行编码:

long sum = 0;
Parallel.For(1, 10, delegate(int i)
    {
        long result = 1;
        Parallel.For(1, i, delegate(int j)
            {
                result = result*j;
            });
        sum = sum + result;
    });

请告诉我怎么走

for (long i = 1; i <= 5; i++)
        {
            sum = sum * i;
        }

Parallel.For(1, 5, delegate(int i)
    {
        sum = sum * i;
    });

结果= 24

正常= 120

对于阶乘(Parallel和Normal),答案并不相同

并行版本的答案是任意的,因为sumresult是由不同的线程访问和修改的。所以你应该做的是把计算每一步和求和结果分开。为了能够正确地总结结果,您需要获得一个锁,以便线程独占地修改sum。一种修复方法是:

long sum = 0;
object monitor = new object(); 
Parallel.For(1, 11, () => 0L, (i, state, local) => 
{ 
    long result = 1;
    for (long j = 1; j <= i; j++)
    {
        result = result*j;
    } 
    return local + result;
}, local => { lock (monitor) sum += local; }); 

注意,您很少需要两个嵌套的Parallel.For循环,因为它们通常会导致糟糕的性能。因此,建议在最外层设置一个Parallel.For循环,并保持内部for循环的原样。同样,为了获得一些加速,您必须使用比10大得多的数字进行测试。

我发现了一种并行计算阶乘的快速方法。

    public static BigInteger Factorial(int n)
    {
        BigInteger temp = 1;
        Parallel.For(1, n + 1, (i) =>
        {
            temp *= i;
        });
        return temp;
    }