我有一个非常庞大的词典,其中的内容看起来像这样:
(字典中不包括标题)
(code) (names)
------------------------------
910235487 Diabetes, tumors, sugar sick, .....
我有超过150K行这种字典中的匹配对。
用户输入是关键词(诊断名称),我无法通过关键词搜索字典。
这是代码:
var relevantIDs = this.dic.Where(ele => ele.Value.Contains(keyword)).Select(n => Convert.ToUInt64(n.Key));
字典是
Dictionary<string, string>
,我必须使用字符串作为键的数据类型,因为代码有时会包含字符。名称列包含相关诊断名称的列表。所以我也不能更改这个数据类型。我认为问题在于对于每个值对,我都执行了
Contains
操作,这会减慢整个过程,但我找不到其他方法...以下是我为了查找匹配代码所做的操作。但是,此代码的性能非常差(单行代码需要大约5分钟才能完成)。
有人可以帮忙吗?
更新和最简单的解决方案: 最终我发现搜索速度如此缓慢的原因,并通过以下方式解决:
var relevantStringIDs = this.dic.Where(ele => ele.Value.Contains(keyword)).Tolist();
var relevantUlongIDs = relevantStringIDs.Select(n => Convert.ToUInt64(n.Key)).Tolist();
它非常慢的原因是
this.dic.Where(ele => ele.Value.Contains(keyword))
,每当查询的第二部分被执行时,它都会被执行(这是IEnumberable<T>
的特性,我忘记了术语(也许是延迟执行))。因此,我使用ToList()
将延迟查询转换为具体存储在内存中的列表,这样结果就可以在将字符串转换为ulongs
时重复使用,而不是为每个转换再次执行查询。如果您发现上述解释有误,请纠正我。
顺便说一下,虽然这可能不是最佳解决方案,但更改后的代码性能相当令人满意。代码的第一条语句只需要耗费169毫秒,这对我来说已经足够快了。
ToList
不太可能在这种情况下提高性能。如果您多次迭代最终结果(我假设您是这样做的),那么您主要从最终ToList
中受益。尝试将代码从dic.Where(...).ToList().Select(...).ToList()
更改为dic.Where(...).Select(...).ToList()
-您几乎不会观察到性能上的任何变化。 - Douglas