我决定将数据库记录倒入List<>模型并使用可枚举的Linq从中获取记录。它有141,856条记录。我们发现的是它很慢。
那么,有关使其快速运行的任何建议或建议吗?
public class Geography
{
public string Zipcode { get; set; }
public string City { get; set; }
public string State { get; set; }
}
var geography = new List<Geography>();
geography.Add(new Geography() { Zipcode = "32245", City = "Jacksonville", State = "Florida" });
geography.Add(new Geography() { Zipcode = "00001", City = "Atlanta", State = "Georgia" });
var result = geography.Where(x => (string.Equals(x.Zipcode, "32245", String Comparison.InvariantCulterIgnoreCase))).FirstOrDefault();
当我们在库存中有86,000辆车时,我们希望使用并行任务来快速完成,但是在查找地理位置时它变得非常慢。
await Task.WhenAll(vehicleInventoryRecords.Select(async inventory =>
{
var result = geography.Where(x => (string.Equals(x.Zipcode, inventory.Zipcode, String Comparison.InvariantCulterIgnoreCase))).FirstOrDefault();
}));
答案 0 :(得分:2)
使用dictionary<string, Geography>
存储地理数据。按键查找字典中的数据是O(1)
操作,而列表中的数据是O(n)
答案 1 :(得分:0)
你没有提到你的邮政编码是否是唯一的,所以我认为它们不是。如果是 - 请查看Giorgi's answer并跳到我的答案的第2部分。
<强> 1。使用查找
由于您要通过同一媒体资源多次查找geography
列表,因此您应该按Zipcode
对这些值进行分组。您可以使用ToLookup
轻松完成此操作 - 这将创建一个Lookup
对象。它类似于Dictionary
,但它可以是多个值,因为它的值。将StringComparer.InvariantCultureIgnoreCase
作为第二个参数传递给ToLookup
会使其不区分大小写。
var geography = new List<Geography>();
geography.Add(new Geography { Zipcode = "32245", City = "Jacksonville", State = "Florida" });
geography.Add(new Geography { Zipcode = "00001", City = "Atlanta", State = "Georgia" });
var geographyLookup = geography.ToLookup(x => x.Zipcode, StringComparer.InvariantCultureIgnoreCase);
var result = geographyLookup["32245"].FirstOrDefault();
这会大大提高你的表现。
<强> 2。与PLINQ并行化
您对查找进行并行化的方式值得怀疑。幸运的是,.NET有PLINQ
。您可以使用AsParallel
和并行Select
来异步迭代vehicleInventoryRecords
,如下所示:
var results = vehicleInventoryRecords.AsParallel().Select(x => geographyLookup[x].FirstOrDefault());
使用Parallel.ForEach
是另一个不错的选择。