我有以下 LINQ 查询。
有一个大约 55 000 个项目的列表。我需要对项目内的属性的 三个 进行搜索。
这是我的代码:
private List<Device> Devices = _db.Devices.ToList();
public Device TryFindDeviceInNetworks(ALL_Sims sim)
{
var ips = new List<string>();
if (sim.IP1 != null)
{
ips.Add(sim.IP1);
}
if (sim.IP2 != null)
{
ips.Add(sim.IP2);
}
var device =
Devices.FirstOrDefault(
x => ips.Contains(x.IPaddress1)
|| ips.Contains(x.IPaddress2)
|| ips.Contains(x.IPaddress3));
return device;
}
目前这个操作需要一些时间。
我有一个 for 循环遍历大约 100k 个项目,并且在它的每次迭代中调用这个函数
TryFindDeviceInNetworks()
。它在英特尔 i5 上运行 8 - 10 小时以上。显然这是单线程的。我的问题是如何加快速度?我已经将我的一些列表转换为字典,我可以在应用程序中使用它,这有很大帮助,但是在这种情况下我不能只搜索一个键?
是否有某种数据结构比
List<T>
更适合?数据库不在本地位于 LAN 上,因此每次迭代都会添加至少 ~40 毫秒 + 查询时间的估计 ping。
最佳答案
您可以拥有 3 个字典,而不是拥有一个包含所有 3 个 IP 地址的字典:
private List<Device> Devices = new List<Device>();
private Dictionary<string, Device> mapIP1;
private Dictionary<string, Device> mapIP2;
private Dictionary<string, Device> mapIP3;
您必须在进行搜索之前初始化它们:
public void InitializeDictionaries()
{
mapIP1 = Devices.ToDictionary(x => x.IPaddress1);
mapIP2 = Devices.ToDictionary(x => x.IPaddress2);
mapIP3 = Devices.ToDictionary(x => x.IPaddress3);
}
搜索本身可以使用
TryGetValue
:public Device TryFindDeviceInNetworks(ALL_Sims sim)
{
Device device = null;
if (sim.IP1 != null)
{
if (mapIP1.TryGetValue(sim.IP1, out device))
return device;
if (mapIP2.TryGetValue(sim.IP1, out device))
return device;
if (mapIP3.TryGetValue(sim.IP1, out device))
return device;
}
if (sim.IP2 != null)
{
if (mapIP1.TryGetValue(sim.IP2, out device))
return device;
if (mapIP2.TryGetValue(sim.IP2, out device))
return device;
if (mapIP3.TryGetValue(sim.IP2, out device))
return device;
}
return device;
}
您必须确保
Devices
列表中没有共享相同地址的元素,因为 Dictionary<TKey, TValue>
不能使用重复键。关于c# - 如何使用列表对象中 3 个属性的搜索条件加快 List<> 上的此 linq 查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28568494/