因为Parallel.For
应该用于有点沉重的事情,而不是简单的数字相加!仅使用委托(j, loop, subtotal) =>
可能就足以多提供 10-20% 的时间。而且我们甚至没有谈论线程开销。在 for 循环中看到一些针对代表夏季的基准测试,不仅看到“真实世界”时间,而且看到 CPU 时间,这会很有趣。
我什至添加了与“简单”委托的比较,它与委托做同样的事情Parallel.For<>
。
嗯......现在我的电脑上有一些 32 位的数字(AMD 六核)
32 bits
Parallel: Ticks: 74581, Total ProcessTime: 2496016
Base : Ticks: 90395, Total ProcessTime: 312002
Func : Ticks: 147037, Total ProcessTime: 468003
Parallel 在挂墙时间快一点,但在处理器时间慢 8 倍 :-)
但在 64 位:
64 bits
Parallel: Ticks: 104326, Total ProcessTime: 2652017
Base : Ticks: 51664, Total ProcessTime: 156001
Func : Ticks: 77861, Total ProcessTime: 312002
修改后的代码:
Console.WriteLine("{0} bits", IntPtr.Size == 4 ? 32 : 64);
var cp = Process.GetCurrentProcess();
cp.PriorityClass = ProcessPriorityClass.High;
const int size = 10000000;
int[] nums = new int[size];
Parallel.For(0, size, i => { nums[i] = 1; });
GC.Collect();
GC.WaitForPendingFinalizers();
long total = 0;
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
Parallel.For<long>(
0, size, () => 0,
(j, loop, subtotal) =>
{
return subtotal + nums[j];
},
(x) => Interlocked.Add(ref total, x)
);
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Parallel: Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}
GC.Collect();
GC.WaitForPendingFinalizers();
total = 0;
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < size; ++i)
{
total += nums[i];
}
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Base : Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}
GC.Collect();
GC.WaitForPendingFinalizers();
total = 0;
Func<int, int, long, long> adder = (j, loop, subtotal) =>
{
return subtotal + nums[j];
};
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < size; ++i)
{
total = adder(i, 0, total);
}
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Func : Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}