我有一个包含8个字段的DTO列表,列表中有477.000条记录从XML文件加载,当我在此列表中过滤项目时,CPU在一个核心中消耗了25%,我认为这种行为是因为List没有编入索引,是否列出了可靠的索引?
DTO
public class PriceDto
{
public string Filter { get; set; }
public string Material { get; set; }
public string Value { get; set; }
public string Currency { get; set; }
public string Max { get; set; }
public string Min { get; set; }
public string PorcentValue { get; set; }
public string PromotionPrice { get; set; }
public string ConditionClass { get; set; }
public string Vat { get; set; }
}
Linq查询
Price = AllPrices.FirstOrDefault(x => x.Filter == FilterId.ConsecutiveFilter.Trim() &&
x.ConditionClass == accessSequenceItem.PriceCondition &&
x.Material == CodeMaterial);
答案 0 :(得分:1)
您可以使用LINQ创建Lookup
或Dictionary<Lookup>
甚至Dictionary<Dictionary<Lookup>>
,然后将其用于查询。这会占用时间空间,但改进实际上取决于不同领域中值的分布。在100个过滤器,100种材料和25种条件的随机样本数据集中有500,000个,对过滤器和材料进行索引可以产生2000个随机查询的最快结果,比普通查询快约33倍。通过查找,对不存在的数据的查询速度提高了60到800倍。
以下是创建双索引结构的代码:
var filterMaterialMap = AllPrices.GroupBy(ap => ap.Filter).ToDictionary(apfg => apfg.Key, apfg => apfg.ToLookup(ap => ap.Material));
您运行如下查询:
PriceDto Price = null;
if (filterMaterialMap.TryGetValue(FilterId.ConsecutiveFilter.Trim(), out var matDict))
Price = matDict[CodeMaterial].FirstOrDefault(ap => ap.ConditionClass == accessSequenceItem.PriceCondition);
其他案例是单个字段索引:
var filterMap = AllPrices.ToLookup(ap => ap.Filter);
var Price = filterMap[FilterId.ConsecutiveFilter.Trim()].FirstOrDefault(ap => ap.Material == CodeMaterial && ap.ConditionClass == accessSequenceItem.PriceCondition);
并将所有三个字段编入索引:
var filterMaterialConditionMap = AllPrices.GroupBy(ap => ap.Filter)
.ToDictionary(apfg => apfg.Key, apfg => apfg.GroupBy(ap => ap.Material)
.ToDictionary(apfmg => apfmg.Key, apfmg => apfmg.ToLookup(ap => ap.ConditionClass)));
PriceDto Price = null;
if (filterMaterialConditionMap.TryGetValue(FilterId.ConsecutiveFilter.Trim(), out var matDict))
if (matDict.TryGetValue(CodeMaterial, out var condDict))
Price = condDict[accessSequenceItem.PriceCondition].FirstOrDefault();