博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

LINQ Dictionary加速查询(TryGetValue)

Posted on 2013-05-18 17:58  快乐家++  阅读(1914)  评论(0编辑  收藏  举报

在程序中常会有这样的代码。
多了可能会影响效率。

Dictionary<Key, Value> dict = new Dictionary<Key, Value>();
...........

if (dict.ContainsKey(key))
{
Value value = dict[key];
}


看来没有什么问题。
但是在实际项目中,这种代码一般会写在底层的class中。
它被调用的次数 相当大时,需要优化。

MS.Net2.0如何实现:

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback
{
public bool ContainsKey(TKey key)
{
return (this.FindEntry(key) >= 0);
}
public TValue this[TKey key]
{
get
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
}


FindEntry()被调用了2次!这就导致速度变慢了1倍!

解决方案:估计微软自己也发现 了,所以在2.0里面封装了一个新的method:

public bool TryGetValue(TKey key, out TValue value)
{
int index = this.FindEntry(key);
if (index >= 0)
{
value = this.entries[index].value;
return true;
}
value = default(TValue);
return false;
}


于是,上面的代码就可以改写成:

Dictionary<Key, Value> dict = new Dictionary<Key, Value>();
...........
Value value;
if (dict.TryGetValue(key, out value))
{
value.......
}


使用TryGetValue,FindEntry 只调用了一次,同时判断了有没有也得到了值。 
在程序中常会有这样的代码。
多了可能会影响效率。

Dictionary<Key, Value> dict = new Dictionary<Key, Value>();
...........

if (dict.ContainsKey(key))
{
Value value = dict[key];
}


看来没有什么问题。
但是在实际项目中,这种代码一般会写在底层的class中。
它被调用的次数 相当大时,需要优化。

MS.Net2.0如何实现:

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback
{
public bool ContainsKey(TKey key)
{
return (this.FindEntry(key) >= 0);
}
public TValue this[TKey key]
{
get
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
}


FindEntry()被调用了2次!这就导致速度变慢了1倍!

解决方案:估计微软自己也发现 了,所以在2.0里面封装了一个新的method:

public bool TryGetValue(TKey key, out TValue value)
{
int index = this.FindEntry(key);
if (index >= 0)
{
value = this.entries[index].value;
return true;
}
value = default(TValue);
return false;
}


于是,上面的代码就可以改写成:

Dictionary<Key, Value> dict = new Dictionary<Key, Value>();
...........
Value value;
if (dict.TryGetValue(key, out value))
{
value.......
}


使用TryGetValue,FindEntry 只调用了一次,同时判断了有没有也得到了值。