这些方法的作用是什么

本文关键字:作用 是什么 方法 | 更新日期: 2023-09-27 18:20:13

我找到了两种不同的方法来从数组中获取Max值,但我并不喜欢并行编程,所以我真的不理解它。

我想知道这些方法是一样的,还是我遗漏了什么?我真的没有太多关于他们的信息。甚至没有评论。。。

第一种方法:

int[] vec = ... (I guess the content doesn't matter)
static int naiveMax()
{
    int max = vec[0];
    object obj = new object();
    Parallel.For(0, vec.Length, i =>
    {
        lock (obj) {
                if (vec[i] > max) max = vec[i];
        }
    });
    return max;
}

第二个:

static int Max()
{
    int max = vec[0];
    object obj = new object();
    Parallel.For(0, vec.Length,     //could be Parallel.For<int>
        () => vec[0],
        (i, loopState, partial) =>
    {
        if(vec[i]>partial) partial = vec[i];
        return partial;
    },
    partial => {
            lock (obj) {
                    if( partial > max) max = partial;
            }
    });
    return max;
}

这些是相同的还是不同的?谢谢;)

这些方法的作用是什么

两者都在整数数组中找到最大值。为了更快地找到最大值,他们使用parallel.For方法"并行"进行。不过,这两种方法都失败了。

要看到这一点,我们首先需要一个足够大的整数数组。对于小数组,并行处理无论如何都不会给我们带来加速。

int[] values = new int[100000000];
Random random = new Random();
for (int i = 0; i < values.Length; i++)
{
    values[i] = random.Next();
}

现在我们可以运行这两种方法,看看它们需要多长时间。使用适当的性能测量设置(Stopwatch,100000000个整数的数组,100次迭代,Release构建,没有附加调试器,JIT预热),我在我的机器上得到了以下结果:

naiveMax   00:06:03.3737078
Max        00:00:15.2453303

因此MaxnaiveMax好得多(6分钟!咳嗽)。

但它与PLINQ相比如何?

static int MaxPlinq(int[] values)
{
    return values.AsParallel().Max();
}
MaxPlinq   00:00:11.2335842

不错,节省了几秒钟。现在,一个简单的、旧的、顺序的for循环用于比较呢?

static int Simple(int[] values)
{
    int result = values[0];
    for (int i = 0; i < values.Length; i++)
    {
        if (result < values[i]) result = values[i];
    }
    return result;
}
Simple     00:00:05.7837002

我认为我们有赢家。

经验教训:并行。因为不是你可以撒在代码上的精灵灰尘让它神奇地跑得更快。如果性能很重要,请使用正确的工具和度量,度量measure。。。

它们似乎在做同样的事情,但效率非常低。并行化的目的是提高可以独立执行的代码的速度。由于竞争条件,发现最大值(如这里所实现的)需要对实际逻辑进行原子信号量/锁定。。。这意味着你正在旋转许多线程和相关资源,只是为了按顺序执行代码。。。完全违背了并行化的目的。