在.Net中AsParallel().ForAll和ForEach性能对比
在.Net中AsParallel().ForAll和ForEach性能对比
Array.AsParallel().ForAll(){}
AsParallel().ForAll 是 C# 中用于并行处理集合元素的方法。它允许您以并行的方式对集合中的每个元素执行指定的操作。
AsParallel()
是一个扩展方法,它将一个普通的可枚举集合转换为一个并行查询。通过将查询转换为并行查询,可以利用多核处理器和多线程来并行处理集合中的元素,以提高执行效率。
ForAll()
是并行查询的一个终止操作,它对并行查询中的每个元素执行指定的操作。与普通的 foreach 循环不同,ForAll()
方法可以并行地处理集合中的元素,从而提高处理速度。
以下是使用 AsParallel().ForAll
方法的一些注意事项:
-
AsParallel()
方法只有在集合中的元素数量较大时才会带来性能上的提升。对于较小的集合,串行处理可能更快。 -
ForAll()
方法是一个阻塞操作,它会等待所有并行任务完成后才会返回。因此,如果您需要并行处理集合元素但不需要等待结果,可以考虑使用Parallel.ForEach()
方法。 -
并行处理集合时,操作的执行顺序可能与元素在集合中的顺序不一致。如果您需要保持操作的顺序,可以使用
AsOrdered()
方法。 -
并行处理集合时,操作必须是线程安全的。确保在操作中不会修改共享的状态或资源,或者使用适当的同步机制来处理共享状态。
总之,AsParallel().ForAll
方法可以帮助您以并行的方式高效地处理大型集合中的元素,从而提高程序的性能。但请注意在使用并行处理时要谨慎处理共享状态和资源,以避免并发问题。
Array.ForEach(){}
ForEach()
是 C# 中用于遍历集合元素并执行指定操作的方法。与 AsParallel().ForAll()
不同,ForEach()
方法是在单线程中按顺序处理集合元素的。
以下是关于 ForEach()
方法的一些特点和注意事项:
-
ForEach()
方法是一个阻塞操作,它会按顺序遍历集合中的每个元素并执行指定的操作。 -
ForEach()
方法适用于小型集合或不需要并行处理的场景。对于大型集合或需要并行处理的场景,可以考虑使用AsParallel().ForAll()
方法来提高处理速度。 -
ForEach()
方法不能保证操作的执行顺序与集合中元素的顺序一致。如果需要保持操作的顺序,可以使用普通的foreach
循环。 -
在操作中要注意线程安全性,确保不会修改共享的状态或资源。如果需要修改共享状态,应使用适当的同步机制来确保线程安全。
-
ForEach()
方法是 List类的扩展方法,因此只能应用于 List 类型的集合。如果要在其他类型的集合上使用 ForEach()
,可以先将其转换为 List。 对比示例代码
创建一个新的控制台应用,复制下列代码并运行
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
public class Program
{
private static List<int> currentCountList = new List<int> ();
private static int currentCount = 0;
private static int currentCount1 = 0;
private static int currentCount2 = 0;
private static int currentCount3 = 0;
public static void Main(string[] args)
{
for (int i = 0; i < 900000000; i++)
{
currentCountList.Add(i);
}
Stopwatch stopwatch = new Stopwatch();
// 测试 IncrementCount 方法的运行时间
stopwatch.Start();
IncrementCount();
stopwatch.Stop();
Console.WriteLine($"IncrementCount 方法的运行时间:{stopwatch.Elapsed}");
// 测试 IncrementCount1 方法的运行时间
stopwatch.Reset();
stopwatch.Start();
IncrementCount1();
stopwatch.Stop();
Console.WriteLine($"IncrementCount1 方法的运行时间:{stopwatch.Elapsed}");
}
private static void IncrementCount()
{
currentCountList.AsParallel().ForAll(p =>
{
currentCount++;
currentCount1++;
});
}
private static void IncrementCount1()
{
currentCountList.ForEach(p =>
{
currentCount2++;
currentCount3++;
});
}
}
最终显示结果
IncrementCount 方法的运行时间:00:00:15.7247328
IncrementCount1 方法的运行时间:00:00:02.1774940
最终结果显示,在数据量少的情况下,Array.ForEach(){}的运行速度比Array.AsParallel().ForAll(){}要快上很多,所以在使用的时候需要结合当前实际情况决定.