Dictionary里使用struct,enum做key
生活随笔
收集整理的這篇文章主要介紹了
Dictionary里使用struct,enum做key
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
首先看下Dictionary的源碼
public void Add (TKey key, TValue value){if (key == null)throw new ArgumentNullException ("key");// get first item of linked list corresponding to given keyint hashCode = hcp.GetHashCode (key) | HASH_FLAG;int index = (hashCode & int.MaxValue) % table.Length;int cur = table [index] - 1;// walk linked list until end is reached (throw an exception if a// existing slot is found having an equivalent key)while (cur != NO_SLOT) {// The ordering is important for compatibility with MS and strange// Object.Equals () implementationsif (linkSlots [cur].HashCode == hashCode && hcp.Equals (keySlots [cur], key))throw new ArgumentException ("An element with the same key already exists in the dictionary.");cur = linkSlots [cur].Next;}if (++count > threshold) {Resize ();index = (hashCode & int.MaxValue) % table.Length;}// find an empty slotcur = emptySlot;if (cur == NO_SLOT)cur = touchedSlots++;else emptySlot = linkSlots [cur].Next;// store the hash code of the added item,// prepend the added item to its linked list,// update the hash tablelinkSlots [cur].HashCode = hashCode;linkSlots [cur].Next = table [index] - 1;table [index] = cur + 1;// store item's data keySlots [cur] = key;valueSlots [cur] = value;generation++;}int hashCode = hcp.GetHashCode (key) | HASH_FLAG;
hcp
[Serializable]sealed class DefaultComparer : EqualityComparer<T> {public override int GetHashCode (T obj){if (obj == null)return 0;return obj.GetHashCode ();}public override bool Equals (T x, T y){if (x == null)return y == null;return x.Equals (y);}}其實(shí)就是走到obj.GetHashCode,如果obj.GetHashCode沒有覆蓋的話,那就會(huì)走到ValueType的GetHashCode
public override int GetHashCode (){object[] fields;int result = InternalGetHashCode (this, out fields);if (fields != null)for (int i = 0; i < fields.Length; ++i)if (fields [i] != null)result ^= fields [i].GetHashCode ();return result;}注意看
[MethodImplAttribute (MethodImplOptions.InternalCall)]internal extern static int InternalGetHashCode (object o, out object[] fields); int result = InternalGetHashCode (this, out fields);會(huì)把this轉(zhuǎn)成object類型,第1次boxing,而且會(huì)把每個(gè)字段都轉(zhuǎn)成object,放入fields里,所以會(huì)有多次gc alloc
這個(gè)是不重載GetHashCode導(dǎo)致的gc alloc。
下一個(gè)是 if (linkSlots [cur].HashCode == hashCode && hcp.Equals (keySlots [cur], key))
hcp.Equals
如果T沒有實(shí)現(xiàn)IEquatable,就會(huì)走到DefaultCOmparer,然后會(huì)走到
這個(gè)Equals會(huì)調(diào)用ValueType.Equals
internal static bool DefaultEquals (object o1, object o2){object[] fields;if (o2 == null)return false;bool res = InternalEquals (o1, o2, out fields);if (fields == null)return res;for (int i = 0; i < fields.Length; i += 2) {object meVal = fields [i];object youVal = fields [i + 1];if (meVal == null) {if (youVal == null)continue;return false;}if (!meVal.Equals (youVal))return false;}return true;}// <summary>// True if this instance and o represent the same type// and have the same value.// </summary>public override bool Equals (object obj){return DefaultEquals (this, obj);}這個(gè)里面會(huì)把x,y都轉(zhuǎn)成object.所以會(huì)有2次boxing
至此所有的boxing都清楚了,工程例子在
https://github.com/yingsz/DictionaryAlloc
消除boxing參考
http://www.bkjia.com/Asp_Netjc/1314145.html
轉(zhuǎn)載于:https://www.cnblogs.com/marcher/p/10150622.html
總結(jié)
以上是生活随笔為你收集整理的Dictionary里使用struct,enum做key的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring boot变量的初始化顺序
- 下一篇: DNA Consensus String