Dictionary里使用struct,enum做key
生活随笔
收集整理的這篇文章主要介紹了
Dictionary里使用struct,enum做key
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先看下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);}}其實就是走到obj.GetHashCode,如果obj.GetHashCode沒有覆蓋的話,那就會走到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);會把this轉成object類型,第1次boxing,而且會把每個字段都轉成object,放入fields里,所以會有多次gc alloc
這個是不重載GetHashCode導致的gc alloc。
下一個是 if (linkSlots [cur].HashCode == hashCode && hcp.Equals (keySlots [cur], key))
hcp.Equals
如果T沒有實現IEquatable,就會走到DefaultCOmparer,然后會走到
這個Equals會調用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);}這個里面會把x,y都轉成object.所以會有2次boxing
至此所有的boxing都清楚了,工程例子在
https://github.com/yingsz/DictionaryAlloc
消除boxing參考
http://www.bkjia.com/Asp_Netjc/1314145.html
轉載于:https://www.cnblogs.com/marcher/p/10150622.html
總結
以上是生活随笔為你收集整理的Dictionary里使用struct,enum做key的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring boot变量的初始化顺序
- 下一篇: DNA Consensus String