【发布时间】:2020-07-30 10:58:18
【问题描述】:
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
class Program
{
private static object _lockObj = new object();
static void Main(string[] args)
{
List<int> collection = Enumerable.Range(1, 100000).ToList();
List<Student> students = new List<Student>(100000);
var options = new ParallelOptions()
{
MaxDegreeOfParallelism = 1
};
var sp = System.Diagnostics.Stopwatch.StartNew();
sp.Start();
Parallel.ForEach(collection, options, action =>
{
lock (_lockObj)
{
var dt = collection.FirstOrDefault(x => x == action);
if (dt > 0)
{
Student student = new Student();
student.ID = dt;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
Console.WriteLine(@"value of i = {0}, thread = {1}",
action,Thread.CurrentThread.ManagedThreadId);
}
}
});
sp.Stop();
double data = Convert.ToDouble(sp.ElapsedMilliseconds / 1000);
Console.WriteLine(data);
}
}
我想尽快循环 100000 条记录 我尝试了 foreach 循环,但循环遍历 100000 条记录并不是很好,然后在我尝试实现 Parallel.ForEach() 以提高我的性能之后,在实际场景中我将收集 Id,我需要查找集合是否 id 退出如果退出然后添加。 性能达到最佳状态 当我评论条件时执行大约需要 3 秒,当我取消注释条件时大约需要 24 秒所以我的问题是有什么方法可以通过在集合中查找 id 来提高我的性能
//var dt = collection.FirstOrDefault(x => x == action);
//if (dt > 0)
//{
Student student = new Student();
student.ID = 1;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
Console.WriteLine(@"value of i = {0}, thread = {1}",
action,Thread.CurrentThread.ManagedThreadId);
//}
【问题讨论】:
-
parallel.foreach 中有一个锁,这意味着每次迭代都将按顺序运行,而不是并行运行。基本上,您采用了 parallel.foreach 并将其转换回一个过于复杂的普通 foreach。您将不得不重组您的代码,以便您可以移除该锁定。
-
你能给我看一个@Lasse V. Karlsen 的例子吗?
-
很遗憾没有,目前仅在 iPhone 上。你需要使用可以被多个线程同时操作和使用的集合类型。
-
处理性能问题的最佳方法是首先分析/测量,然后更改代码。除非您知道瓶颈在哪里,否则不要开始进行更改。
-
是的,我完全同意你@Lasse V. Karlsen
标签: c#