我最近搬到了 C#.net 4。
我喜欢 Parallel.For,但不确定何时使用,何时不使用。我知道当订单对我来说不重要时 - 我会使用它。
但是是否有任何关于使用 Parallels 的开销的测试?意思是,如果我的循环只运行 10 次(并且执行的逻辑很少) - 我应该避免使用 Parallels 吗?有没有拇指规则?
Parallel.For
除非性能有问题,否则我会避免使用。
编写并发运行的代码通常比编写单线程代码更难。此外,如果您由于并发问题而出错,则可能很难对其进行调试。例如,该错误可能仅在某些时候出现并且不容易重现。除非您特别需要提高性能,否则我建议您保持简单并在单个线程上使用普通循环。
Parallel.For 循环使用 ThreadPool 在循环中执行工作,方法是在循环的每次迭代中调用一次委托。
Parallel.For 工作原理的大致思路如下:
public static void MyParallelFor(int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body)
{
// Get the number of processors, initialize the number of remaining
// threads, and set the starting point for the iteration.
int numProcs = Environment.ProcessorCount;
int remainingWorkItems = numProcs;
int nextIteration = inclusiveLowerBound;
using (ManualResetEvent mre = new ManualResetEvent(false))
{
// Create each of the work items.
for (int p = 0; p < numProcs; p++)
{
ThreadPool.QueueUserWorkItem(delegate
{
int index;
while ((index = Interlocked.Increment(ref nextIteration) - 1) < exclusiveUpperBound)
body(index);
if (Interlocked.Decrement(ref remainingWorkItems) == 0)
mre.Set();
});
}
// Wait for all threads to complete.
mre.WaitOne();
}
}
Parallel.For 返回 ParallelLoopResult 值类型,其中包含有关已完成循环的详细信息。它的重载之一如下:
public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);
重要的是要意识到并行执行并不总是比串行执行快。要决定是否使用并行,您必须估计每次循环迭代的工作量。如果循环实际执行的工作相对于线程同步开销来说很小,那么最好使用普通循环。
这是串行 for 循环性能比并行更快的示例之一:
static void Main(string[] args)
{
Action<int> action = new Action<int>(SimpleMethod);
// ordinary For loop performance estimation
var sw = Stopwatch.StartNew();
for(int i = 0; i < 1000; i++)
action(i);
Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);
// parallel For loop performance estimation
sw = Stopwatch.StartNew();
Parallel.For(0, 1000, action);
Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);
}
static void SimpleMethod(int index)
{
int d = 1;
int result = index / d;
}
输出:
0.0001963 sec.
0.0346729 sec.
引用 SQLite 常见问题解答:'线程是邪恶的。避开他们'
并行化对性能很有用。应用程序性能优化是软件设计中最违反直觉的事情之一,应该非常小心,使用正确的测量工具,否则看起来很有趣。
有些人会优化 UI 代码以在微秒而不是毫秒内响应,显然没有价值并造成大量损坏。