- 先看代码:
public void Update()
{
DictionaryTest();
}
public void DictionaryTest()
{
if (!mBInited)
{
mBInited = true;
m_States.Add(State.None, 0);
m_States.Add(State.Start, 0);
m_States.Add(State.Stop, 0);
}
int none = m_States[State.None];
}
private bool mBInited = false;
Dictionary<State, int> m_States = new Dictionary<State, int>();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
2.运行结果(内存消耗)
3.原因分析
先看Dictionary
[__DynamicallyInvokable]
public TValue this[TKey key]
{
[__DynamicallyInvokable]
get
{
int num = this.FindEntry(key);
if (num >= 0)
{
return this.entries[num].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
set
{
this.Insert(key, value, false);
}
}
// System.Collections.Generic.Dictionary<TKey, TValue>
private int FindEntry(TKey key)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (this.buckets != null)
{
int num = this.comparer.GetHashCode(key) & 2147483647;
for (int i = this.buckets[num % this.buckets.Length]; i >= 0; i = this.entries[i].next)
{
if (this.entries[i].hashCode == num && this.comparer.Equals(this.entries[i].key, key))
{
return i;
}
}
}
return -1;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
最终的消耗是在 FindEntry(TKey key)中的this.comparer.GetHashCode(key),而compare这个泛型函数会导致内存的分配涉及到反射typeof(Tkey),
// System.Collections.Generic.Dictionary<TKey, TValue>
private IEqualityComparer<TKey> comparer;
ublic static Comparer<T> Default
{
[__DynamicallyInvokable]
get
{
Comparer<T> comparer = Comparer<T>.defaultComparer;
if (comparer == null)
{
comparer = Comparer<T>.CreateComparer();
Comparer<T>.defaultComparer = comparer;
}
return comparer;
}
}
private static Comparer<T> CreateComparer()
{
RuntimeType runtimeType = (RuntimeType)typeof(T);
if (typeof(IComparable<T>).IsAssignableFrom(runtimeType))
{
return (Comparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), runtimeType);
}
if (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
RuntimeType runtimeType2 = (RuntimeType)runtimeType.GetGenericArguments()[0];
if (typeof(IComparable<>).MakeGenericType(new Type[]
{
runtimeType2
}).IsAssignableFrom(runtimeType2))
{
return (Comparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), runtimeType2);
}
}
return new ObjectComparer<T>();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
|