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) 如下为一 ...
随机推荐
- phoenix查询缓慢问题
现象:phoenix刚建表时查找很快,随着数据导入越来越多,查询越来越缓慢,执行explain这个表的计划都需要好几秒,但在hbase shell里查询很快 问题定位:这个是由于system.stat ...
- ecmall程序结构图与数据库表分析
以下是ecmall的程序结构图,看了这张图,我们可以清楚的知道ecmall的程序结构. ECMALL数据库主要表如下所示: ecm_acategory:存放的是商城的文章分类.ecm_address: ...
- Windows/OS X下制作Mac安装U盘
Windows下制作: 方法一:(适用于OSX 10.9以前) 前期准备:一台windows电脑 UltraISO软件 Mac系统镜像dmg(这里使用Mac os x 10.8.4) 至少8GB的U盘 ...
- linux重命名session和window
重命名 window title 最近想要给screen session中的每一个 窗口命名一个标识名字,而不是默认的 $ bash 相关命令: ctrl+z(我的screen配置的+z,默认是+a) ...
- Mysql root密码忘记的解决办法
Windows 版本: 1.打开安装目录下的my.ini 找到 [mysqld] 在下面加入 skip-grant-tables 2. 重启mysql服务 3.打开命令行 依次输入 USE mysql ...
- CentOS装JDK1.8
1.下载jdk1.8:http://download.csdn.net/download/yichen01010/10017267 直接使用liunx下默认安装的浏览器 下载 2.卸载系统自带的jdk ...
- CodeSmith自动生成代码使用
官网地址:http://www.codesmithtools.com/ CodeSmith开发系列资料总结 http://terrylee.cnblogs.com/archive/2005/12/28 ...
- 嵌入式开发之示波器----tektronix tds2024 的使用
http://jingyan.baidu.com/article/91f5db1bf715c01c7f05e39a.html http://cn.tek.com/learning/oscillosco ...
- java字符编码(转)
转载:http://blog.csdn.net/peach99999/article/details/7231247 深入讨论java乱码问题 几种常见的编码格式 为什么要编码 不知道大家有没有想过一 ...
- 再论IBatisNet + Castle进行项目的开发
随着项目的进展,Castle和IBatisNet给我的惊喜更多.Com+很重,不需要分布式的中小项目慎用,NHibernate虽好,NHibernate的2005-9-20发布了最新版本1.0-rc1 ...