C# 如何提高C语言中foreach循环的性能# 问题1
在并行foreach中使用锁而不是并发集合。强制并行foreach等待,以访问锁,因此将逐个执行 将列表更改为a,然后从ParallelForEach中删除C# 如何提高C语言中foreach循环的性能# 问题1,c#,C#,在并行foreach中使用锁而不是并发集合。强制并行foreach等待,以访问锁,因此将逐个执行 将列表更改为a,然后从ParallelForEach中删除锁 //var dt = collection.FirstOrDefault(x => x == action); //if (dt > 0) //{ Student student = new Student(); studen
锁
//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);
//}
将循环中的访问权限更改为:
var collection = Enumerable.Range(1, 100000)
.ToDictionary(x=> x);
问题3
秒表不是基准测试工具。请使用或使用其他库。您的原始代码正在
并行中执行锁定。这实质上是获取并行代码并强制其串联运行
在我的机器上需要40秒
这实际上相当于这样做:
if(collection.TryGetValue(action, out var dt))
{
//....
}
这也需要40秒
但是,如果您只是这样做:
foreach (var action in collection)
{
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);
}
}
这需要1毫秒才能运行。大约快4万倍
在这种情况下,您可以通过一次迭代集合来获得更快的循环,而不是以嵌套方式,也不是使用Parallel.ForEach
我的ap0ologies因为缺少关于id的部分不存在
试试这个:
foreach (var action in collection)
{
Student student = new Student();
student.ID = action;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
}
运行时间为25毫秒。parallel.foreach中有一个锁,这意味着每个迭代将按顺序运行,而不是并行运行。基本上,您使用parallel.foreach并将其转换回过于复杂的普通foreach。你必须重新构造你的代码,这样才能移除锁。你能给我举一个@Lasse V.Karlsen的例子吗?不幸的是,现在只有在iPhone上。您需要使用可由多个线程同时操作和使用的集合类型。处理性能问题的最佳方法是首先分析/度量,然后更改代码。除非你知道瓶颈在哪里,否则不要开始改变。是的,我完全同意你的观点@Lasse V.karlse这是一个糟糕的解决方案。使用ConcurrentBag
是在现有大量黑客基础上的又一次黑客攻击。我花了大约5秒钟的时间迭代,非常感谢@Preben Huybrechts你说的@Enigmativity是什么意思?我没有理解它?@Enigmativity,请解释一下?正如我所说,这个包相当出色。@ZoyebShaikh-看看我的答案。它在1毫秒内运行。我知道如果我删除FirstOrDefault()条件,速度会快得多,但是我们有选择助手,在实际情况下,用户将选择范围内的行和进程,这就是为什么我必须在集合中查找,我清楚地提到,我知道如果删除FirstOrDefault(),那么它的工作速度会非常快
foreach (var action in collection)
{
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);
}
}
foreach (var action in collection)
{
Student student = new Student();
student.ID = action;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
}
HashSet<int> hashSet = new HashSet<int>(collection);
List<Student> students = new List<Student>(100000);
var sp = System.Diagnostics.Stopwatch.StartNew();
sp.Start();
foreach (var action in collection)
{
if (hashSet.Contains(action))
{
Student student = new Student();
student.ID = action;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
}
}
sp.Stop();
foreach (var action in
from c in collection
join dt in collection on c equals dt
select dt)
{
Student student = new Student();
student.ID = action;
student.Name = "Zoyeb";
student.Email = "ShaikhZoyeb@Gmail.com";
students.Add(student);
}