C# 有没有办法提高这两个foreach循环的性能?
我目前正在为客户开发一个帮助更新客户信息的应用程序。Customers查询至少返回500个结果。CustomerItemList是一个单独的项目列表。两个列表都包含客户主键。我需要合并customerPK匹配的这两个列表。需要注意的是,客户pk可以在客户项目列表中列出多次!下面的代码片段可以工作,但速度非常慢。我希望用linq更新它,但是我还没有发现任何可以提高性能的东西 提前谢谢你的帮助C# 有没有办法提高这两个foreach循环的性能?,c#,linq,foreach,C#,Linq,Foreach,我目前正在为客户开发一个帮助更新客户信息的应用程序。Customers查询至少返回500个结果。CustomerItemList是一个单独的项目列表。两个列表都包含客户主键。我需要合并customerPK匹配的这两个列表。需要注意的是,客户pk可以在客户项目列表中列出多次!下面的代码片段可以工作,但速度非常慢。我希望用linq更新它,但是我还没有发现任何可以提高性能的东西 提前谢谢你的帮助 var Customers = LookupCustomers(CustomerI
var Customers = LookupCustomers(CustomerItemList); //returns 500
foreach (var customer in Customers)
{
var CustomerIDList = CustomerItemList.Where(x => x.CustomerPK.Equals(customer.CustomerPK)).ToList(); //returns at least 2 results
foreach (var CustomerID in CustomerIDList)
{
CustomerID.CustomerPrimaryCard = customer.PrimaryCardID + ", 1";
}
}
如果您的
CustomerItemList
很大,请按照搜索标准对其进行预排序CustomerPK
,然后使用BinarySearch检索搜索项的第一次出现。从那里开始迭代,并与第一个不匹配的CustomerPK
中断。如果您的CustomerItemList
很大,请按照搜索标准对其进行预排序CustomerPK
,并使用BinarySearch检索搜索项的第一次出现。从那里开始迭代,并使用第一个不匹配的CustomerPK
尝试将您的CustomerItemList
转换为字典:
var customersDict = CustomerItemList.GroupBy(c => c.CustomerPK)
.ToDictionary(k => k.Key, v => v.ToList());
然后在foreach
中使用以下代码:
foreach (var customer in Customers)
{
List<CustomerItem> items; // not sure about elements type of CustomerItemList
if (!customersDict.TryGetValue(customer.CustomerPK, out items))
continue;
foreach (var CustomerID in items)
CustomerID.CustomerPrimaryCard = customer.PrimaryCardID + ", 1";
}
foreach(客户中的var客户)
{
列表项;//不确定CustomerItemList的元素类型
如果(!customerDict.TryGetValue(customer.CustomerPK,out items))
继续;
foreach(项目中的var CustomerID)
CustomerID.CustomerPrimaryCard=customer.primaryCard+“,1”;
}
尝试将您的CustomerItemList
转换为字典:
var customersDict = CustomerItemList.GroupBy(c => c.CustomerPK)
.ToDictionary(k => k.Key, v => v.ToList());
然后在foreach
中使用以下代码:
foreach (var customer in Customers)
{
List<CustomerItem> items; // not sure about elements type of CustomerItemList
if (!customersDict.TryGetValue(customer.CustomerPK, out items))
continue;
foreach (var CustomerID in items)
CustomerID.CustomerPrimaryCard = customer.PrimaryCardID + ", 1";
}
foreach(客户中的var客户)
{
列表项;//不确定CustomerItemList的元素类型
如果(!customerDict.TryGetValue(customer.CustomerPK,out items))
继续;
foreach(项目中的var CustomerID)
CustomerID.CustomerPrimaryCard=customer.primaryCard+“,1”;
}
您可以尝试以下方法:
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.ToList()
.ForEach(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.AsParallel()
.ForAll(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
或者,您可以尝试以下方法:
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.ToList()
.ForEach(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.AsParallel()
.ForAll(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
但是,如果您有大量的结果和/或资源密集型操作,则最好使用并行处理。否则,它实际上会变慢
一般的想法是使用集合操作。您可以尝试以下方法:
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.ToList()
.ForEach(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.AsParallel()
.ForAll(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
或者,您可以尝试以下方法:
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.ToList()
.ForEach(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
Customers
.Join(CustomerItemList, c => c.CustomerPK, i => i.CustomerPK, (c, i) => new { Customer = c, Item = i })
.AsParallel()
.ForAll(r => { r.Item.CustomerPrimaryCard = r.Customer.PrimaryCardID + ", 1"; });
但是,如果您有大量的结果和/或资源密集型操作,则最好使用并行处理。否则,它实际上会变慢
一般的想法是使用集合操作。这是实体框架还是其他ORM?应该是客户而不是项目,对吗?对,我只是更新了它。谢谢。这是实体框架还是其他ORM?应该是客户而不是项目,对吗?对,我只是更新一下。谢谢。如果列表中没有客户的项目,则此操作将中断。ToLookup将更好、更安全ASprin试图提出的要点是,而不是执行
。GroupBy(c=>c.CustomerPK)。ToDictionary(k=>k.Key,v=>v.ToList())
您可以将其简化为.ToLookup(c=>c.CustomerPK)代码>当您使用ToLookup时,您可以执行以前的forech,因为无法查找的项目返回一个空IEnumerable,而不是抛出异常或null。如果列表中没有客户的项目,这将中断。ToLookup将更好、更安全ASprin试图做到的一点是,而不是执行。GroupBy(c=>c.CustomerPK).ToDictionary(k=>k.Key,v=>v.ToList());
您可以将其简化为.ToLookup(c=>c.CustomerPK)
当您使用ToLookup时,您可以执行以前的forech,因为无法查找的项返回一个空的IEnumerable,而不是抛出异常或null。谢谢!此解决方案工作得非常好,并且极大地增加了我的性能时间。不要仅仅为了获得.ForEach(…)而使用.ToList()
这将迭代您的集合两次。只需在中的IEnumerable
上使用常规的foreach
关键字。加入(…)
顺便说一句,您的.AsParallel()
除了可能取消集合中的任何订单之外,什么也做不了。谢谢!此解决方案工作得非常好,并且极大地增加了我的性能时间。不要仅仅为了获得.ForEach(…)而使用.ToList()
这将迭代您的集合两次。只需在中的IEnumerable
上使用常规的foreach
关键字。加入(…)
顺便说一句,您的.AsParallel()
除了可能取消集合中的任何顺序外,什么都不会做。