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) 如下为一 ...
随机推荐
- PMON
PMON是一个兼有BIOS和boot loader部分功能的开放源码软件,多用于嵌入式系统. 与BIOS相比功能不足,与常见的bootloader 相比,功能要丰富的多.基于龙芯的系统采用 pmon ...
- OSGi规范概要
目前最新的OSGi规范是2012年7月发布的Release 5,Version5.0(后文简称为R5.0)版本,该规范定义了Java模块化系统所涉及的各种场景(开发.打包.部署.更新和交互等),以及其 ...
- 使用 OpCache 提升 PHP 性能
使用 OpCache 提升 PHP 性能 wdd2007wdd2007 .6k 1月29日 发布 推荐 推荐 收藏 收藏,.3k 浏览 OpCache 通过对 opcode 的缓存和优化来提升 PHP ...
- iOS swift String 换行显示
在oc中换行的方式 NSString *str = @" aaaaa \ bbbbb \ cccc \ "; swift中这种方式不可用 ,swift中换行采用新的方双三引号 &q ...
- python 练习题练习题2--多分支选择
题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万之 ...
- ASP.NET MVC 4新建库项目中找不到 System.Web.Security 的引用
.NET 4中,WebSecurity的引用已经不再System.Web中,而是转移到了System.Web.ApplicationServices Dll中,添加该Dll即可.
- android最佳实践的建议(翻译自android-best-practices)
Best practices in Android development Use Gradle and its recommended project structure 使用Gradle和其推荐的 ...
- 理解Callable 和 Spring DeferredResult(翻译)
1-介绍 Servlet 3中的异步支持为在另一个线程中处理HTTP请求提供了可能性.当有一个长时间运行的任务时,这是特别有趣的,因为当另一个线程处理这个请求时,容器线程被释放,并且可以继续为其他请求 ...
- css3兼容代码
1. 渐变:.gradient{ width:300px; height:150px; filter:alpha(opacity=100 finishopacity=50 style=1 startx ...
- jfinal_BLOG v1.0
http://git.oschina.net/fleam/jfinal_AmazeUI