【发布时间】:2023-03-15 04:46:01
【问题描述】:
我有一个包含大约 7000 个对象的循环,在循环内我需要获取结构列表的不同计数。目前我正在使用 -
foreach (var product in productsToSearch)
{
Console.WriteLine("Time elapsed: {0} start", stopwatch.Elapsed);
var cumulativeCount = 0;
productStore.Add(product);
var orderLinesList = totalOrderLines
.Where(myRows => productStore.Contains(myRows.Sku))
.Select(myRows => new OrderLineStruct
{
OrderId = myRows.OrderId,
Sku = myRows.Sku
});
var differences = totalOrderLines.Except(orderLinesList);
cumulativeCount = totalOrderLinsCount - differences.Select(x => x.OrderId).Distinct().Count();
cumulativeStoreTable.Rows.Add(product, cumulativeCount);
Console.WriteLine("Time elapsed: {0} end", stopwatch.Elapsed);
}
public struct OrderLineStruct
{
public string OrderId { get; set; }
public string Sku { get; set; }
}
获取不同计数时这非常慢。有人知道这样做的更有效方法吗?我曾尝试使用 MoreLinq,它有一个用于 Linq 的 DisctintBy 方法,但它并不高效,因为我已经计时了。我玩过 PLinq,但我有点不确定在哪里并行化这个查询。
所以循环的每次迭代都在 -
经过时间:00:00:37.1142047 开始
经过时间:00:00:37.8310148 结束
= 0.7168101 秒 * 7000 = 5017.6707(83.627845 分钟)
它的 Distinct() Count() 行处理时间最长(大约 0.5 秒)。变量差异有几十万个 OrderLineStruct,因此对此进行任何 linq 查询都很慢。
更新
我稍微修改了循环,现在它运行大约 10 分钟而不是超过 1 小时
foreach (var product in productsToSearch)
{
var cumulativeCount = 0;
productStore.Add(product);
var orderLinesList = totalOrderLines
.Join(productStore, myRows => myRows.Sku, p => p, (myRows, p) => myRows)
.Select(myRows => new OrderLineStruct
{
OrderId = myRows.OrderId,
Sku = myRows.Sku
});
totalOrderLines = totalOrderLines.Except(orderLinesList).ToList();
cumulativeCount = totalOrderLinesCount - totalOrderLines.Select(x => x.OrderId).Distinct().Count();
cumulativeStoreTable.Rows.Add(product, cumulativeCount);
}
在 except 上有一个 .ToList() 似乎有所不同,现在我在每次迭代后删除已经处理的订单,这提高了每次迭代的性能。
【问题讨论】:
-
那么结构是什么样的? minimal reproducible example 真的很有帮助——我们真的对目前发生的事情没有太多线索。
-
你没有使用
product,那么你为什么要在循环中这样做呢?所以我的建议是:把它移出循环,它已经快了 7000 倍。 -
@JamesDev 不,你没有使用
product,你使用的是productStore。为什么不将所有产品添加到 productstore,并将 linq 移到 foreach 之外? -
在您调用
Count之前,您的任何 LINQ(包括在Where中包含嵌套Contains的第一个查询)实际上都不会被评估 - 你 确定 @ 987654330@是瓶颈? -
@Kote var productStore = new HashSet
();