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 key
int 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 () implementations
if (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 slot
cur = 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 table
linkSlots [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 ;
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 = ; 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 = ; i < fields.Length; i += ) {
object meVal = fields [i];
object youVal = fields [i + ];
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
Dictionary里使用struct,enum做key的更多相关文章
- C#中正确使用enum做Key的姿势
C#中自定义enum,然后将其作为Dictionary的Key,通常的做法如下: using System; using System.Text; using System.Collections.G ...
- Unity3D研究之多语言用中文做KEY
做多语言的时候用中文做KEY绝对是有100%的优点,假设用英文表示那么代码里面给文字赋值的地方全都是英文.写的代码多了以后维护起来就没有人能看懂了,或者看起来非常费劲. 对PoolManager ...
- React 等框架使用 index 做 key 的问题
React 等框架使用 index 做 key 的问题 假如有两个树,一个是之前,一个是更变之后,我们抽象成两种可能性. 插入内容在最后 插入内容在最前 关于插在中间,原理一样,就不阐述. 使用 ul ...
- Go语言 判断key是否在map里 if _, ok := map[key]; ok
if val, ok := map[key]; ok { //do something here } 如果key在map里 val 被赋值map[key] ok 是true 否则val得到相应类型的零 ...
- c++ struct enum union加typedef与不加typedef
struct/enum/union加typedef与不加typedef 匿名结构体 struct { int a; int b; } v; // 这里表示定义了一个结构体的变量v,且结构体类型没有名字 ...
- 适当使用enum做数据字典 ( .net c# winform csharp asp.net webform )
在一些应用中,通常会用到很多由一些常量来进行描述的状态数据,比如性别(男.女),审核(未审核.已审核)等.在数据库中一般用数字形式来存储,比如0.1等. 不好的做法 经常看到一些应用(ps:最近又看到 ...
- Dictionary通过Value找到它的key
private void GetDicKeyByValue() { Dictionary<string, string> dic = new Dictionary<string, s ...
- Java学习笔记--HashMap中使用object做key的问题【转】
在HashMap中,如果需要使用多个属性组合作为key,可以将这几个属性组合成一个对象作为key.但是存在的问题是,要做get时,往往没办法保存当初put操作时的key object的referenc ...
- C# Dictionary通过value获取对应的key值
1:最直白的循环遍历方法,可以分为遍历key--value键值对以及所有的key两种表现形式 2:用Linq的方式去查询(当然了这里要添加对应的命名空间 using System.Linq) 如下为一 ...
随机推荐
- [elk]logstash grok原理
logstash语法 http://www.ttlsa.com/elk/elk-logstash-configuration-syntax/ https://www.elastic.co/guide/ ...
- [na] centos如何通过vmware Windows共享文件
参考 自我感觉都会使用Windows中的文件.在Windows与linux之间互传文件是一个问题.本方法介绍的是在linux下挂载Windows共享文件夹的方法来实现的 首先安装VMware Tool ...
- Postman 常用操作
一,入参为json 格式 实例:添加学生信息,这个接口是用来讲入参式json 类型的 二,上传文件 三,添加header 信息 实例:获取所有学生信息 四,添加cookie以及身份验证 实例:学生金币 ...
- poj 2846 Repository
题目大意:给你n个字符串,然后给你m个子串,看这个子串在上面的多少个串中,出现过: 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846 本题可以在字 ...
- Jquery学习笔记(2)--五角星评分
网购五星评分模拟: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- SQLi-Labs学习笔记
结构化查询语言,也叫做SQL,从根本上说是一种处理数据库的编程语言.对于初学者,数据库仅仅是在客户端和服务端进行数据存储.SQL通过结构化查询,关系,面向对象编程等等来管理数据库.编程极客们总是搞出许 ...
- 详解 SWT 中的 Browser.setUrl(String url, String postData, String[] headers) 的用法
http://hi.baidu.com/matrix286/item/b9e88b28b90707c9ddf69a6e ———————————————————————————————————————— ...
- Switch选择语句能否作用在String【字符串】上,也就是能否这么写:Switch(一个字符串变量)?
Switch选择语句能否作用在String[字符串]上,也就是能否这么写:Switch(一个字符串变量)? 解答:不可以,只能处理int,byte,short,char,(其实是只能处理int,其它三 ...
- 要生成一个窗口,通常使用Window的子类Frame类进行实例化
要生成一个窗口,通常使用Window的子类Frame类进行实例化,而不是直接使用Window 类,框架的外观就像平常Windows系统下的窗口,有标题.边框. 菜单 和大小等. setSize()方法 ...
- 2017 ACM区域赛(南宁站) 参赛流水账
day0: 早上四点起床赶飞机,还好没有吵醒室友导致被打死.本来想在飞机上准备一下下周的小测,结果飞机一点都不平稳,只能全程和队友吹逼聊天.下午在宾馆里和johann通关了一部合金弹头,重温了童年的经 ...