这些方法的作用是什么
本文关键字:作用 是什么 方法 | 更新日期: 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
因此Max
比naiveMax
好得多(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。。。
它们似乎在做同样的事情,但效率非常低。并行化的目的是提高可以独立执行的代码的速度。由于竞争条件,发现最大值(如这里所实现的)需要对实际逻辑进行原子信号量/锁定。。。这意味着你正在旋转许多线程和相关资源,只是为了按顺序执行代码。。。完全违背了并行化的目的。