上下文是我在内存中有一组高速缓存的值,这些值很难获取,而另一组相关数据的获取成本低廉且无法缓存(业务规则)。我已经完成了所有工作,但我只是想知道是否有人能想到一种更便宜的方式进行这种更新......
foreach (var nonCachedItem in searchItemsNonCached)
{
foreach (var cachedItem in searchItemsCached)
{
if (cachedItem.ID == nonCachedItem.ID)
nonCachedItem.Description = cachedItem.Description;
}
}
它基本上只是将缓存的信息与我刚收到的信息相匹配。这一切都有效,负载几乎可以忽略不计,但我对提高效率很有帮助。
编辑:在上面,searchItemsNonCached和searchItemsCached都是SearchItem的列表,其中Searchitem是一个定制的对象。
答案 0 :(得分:5)
将缓存的项目存储在字典中。现在只有在密钥存在时才能更新。
答案 1 :(得分:2)
使用缓存的项加载Dictionary
,然后循环浏览每个非缓存项,以查找字典中的匹配项。这是O(n)
,而不是嵌套循环O(n^2)
。
var cachedDictionary = new Dictionary<int, YourType>();
foreach (var item in searchItemsCached)
{
cachedDictionary.Add(item.ID, item);
}
foreach (var item in searchItemsNonCached)
{
YourType match;
if (cachedDictionary.TryGetValue(out match))
{
item.Description = match.Description;
}
}
如果您可以考虑从一开始就使用Dictionary
作为缓存项目(而不是List
),那么您可以避免在找到匹配项之前加载它的步骤。
答案 2 :(得分:0)
你要做的事实上是一个连接(在数据库意义上),特别是一个equi-join。您可以查看关于连接算法的this section of a Wikipedia article。上面列出的代码是嵌套循环连接,adymitruk的建议是散列连接,但正如Lou Franco评论的那样,最好的方法可能取决于您的集合有哪种排序或结构(如果有的话)。
如果searchItemCached
只是一个无序列表,那么hash join可能是你最好的选择 - 只需从一个集合或另一个以ID作为密钥构建字典,然后循环遍历查找字典中匹配项的其他集合。如果searchItemCached
已经是由ID键入的字典,那么散列连接绝对是您最好的选择。如果searchItemCached
和searchItemsNonCached
都按ID排序,则可能需要sort-merge join。
答案 3 :(得分:-1)
另一种方法是你可以编写一个linq表达式并在ID上加入两个列表,并使用更新的值创建相同类型的新对象。
离
from nc in searchItemsNonCached
join c in searchItemCached on nc.ID equals c.ID
select new (same type) // and assign the desc from c.Description