【Unity主程手记(摘录)】第一章(二) - Dictory 底层源码剖析
第一章(二) - Dictory 底层源码剖析
提示:个人学习总结,如有错误,敬请指正。
文章目录
- 第一章(二) - Dictory 底层源码剖析
- 一.Dictory
- 1.底层数据结构
- 2.Add - 添加数据
- 3.Remove- 删除数据
- 4.其他接口
- 5.Hash函数的创建过程
- 6.线程安全
- 7.总结
- 附录
一.Dictory
1.底层数据结构
Key和Value用一个Hash函数来建立映射关系,处理Hash哈希冲突的方法在数据结构中会有详细讲解
Dictionary 是以数组为底层数据结构的类。当我们实例化 new Dictionary() 后,内部的数组是0个数组的状态。与 List 组件一样,Dictionary 也是需要扩容的,会随着元素数量的增加而不断扩容。
2.Add - 添加数据
Add 接口就是 Insert 的代理
返回一个size需要的最小质数值,首次定义为3每次扩容两倍-即3->7->17->37(每次都是质数)
int size = HashHelpers.GetPrime(capacity);
对Hash地址执行余数操作确保再数组长度方范围内不溢出。
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;int targetBucket = hashCode % buckets.Length;
指定数组单元格内的链表元素做遍历操作,找出空出来的位置将值填入;
若数组大小不够则需要再次扩容
3.Remove- 删除数据
- 用哈希函数 comparer.GetHashCode 再除余后得到范围内的地址索引,再做余操作确定地址落在数组范围内,从哈希索引地址开始,查找冲突的元素的Key是否与需要移除的Key值相同,相同则进行移除操作并退出。
- Remove并没有对内存进行删减,而是将对应hash位置置为默认值,这是为了减少内存的频繁操作。
4.其他接口
- ContainsKey :
- 与之前类似,FindEntry使用和前面相同的方式查找key的hash位置,然后从链表里匹配元素,成功返回该索引地址。
- TryGetValue :
- 与 ContainsKey 同样,他调用的也是FindEntry的接口,来获取Key对应的Value值。
5.Hash函数的创建过程
哈希冲突的拉链法贯穿了整个底层数据结构。因此哈希函数是关键了,哈希函数的好坏直接决定了效率高低。
if (t == typeof(byte)) {return (EqualityComparer<T>)(object)(new ByteEqualityComparer());}// If T implements IEquatable<T> return a GenericEqualityComparer<T>if (typeof(IEquatable<T>).IsAssignableFrom(t)) {return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), t);}// If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U>if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) {return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), u);}}
对于数字类型,他们实现了IEquatable接口,直接使用GenericEqualityComparer获得hash函数。否则如果实现了Nullable接口,则调用NullableEquality-Comparer(),如果不是以上两种情况则调用ObjectEqualityComparer。
6.线程安全
和List一样,Dictionary并不是线程安全的
Hashtable在多线程读/写中是线程安全的,而Dictionary不是。如果要在多个线程中共享Dictionary的读/写操作,就要自己写lock,以保证线程安全。
7.总结
- 从效率上看,同List一样最好在 实例化对象时,即 new 时尽量确定大致数量会更加高效,另外用数值方式做Key比用类实例方式作为Key值更加高效率。
- 从内存操作上看,大小以3->7->17->37->….的速度,每次增加2倍多的顺序进行,删除时,并不缩减内存。
- 如果想在多线程中,共享 Dictionary 则需要进行我们自己进行lock操作。
- 减少Dictionary的冗余访问
if(Dic.Contains(key)){var result = Dic[key];}//改写成value result ;if(Dic.TryGetValue(key,out result)){//}
附录
主程手记
【Unity主程手记(摘录)】第一章(二) - Dictory 底层源码剖析相关推荐
- C#要点技术(二) - Dictionary 底层源码剖析
Dictionary 底层代码 我们知道 Dictionary 字典型数据结构,是以关键字Key 和 值Value 进行一一映射的.Key的类型并没有做任何的限制,可以是整数,也可以是的字符串,甚至可 ...
- LightSun/android-databinding(第一篇属性绑定)源码剖析与思考
自从谷歌推出DataBinding框架之后,MVVM开发模式也在android的端慢慢的兴起,用DataBinding框架可以省去UI和数据绑定的不少功夫,通俗的讲就是少写很多代码,并且结构看起来清晰 ...
- 【Unity主程手记学习】第一章——软件架构
架构无处不在,它实质上就是解决生活和工作中问题的一种方式.. 如果把软件比作书,那么软件架构就是书架. 一.架构的好坏由五个因素决定: 1.承载力 能承载多少逻辑系统,能承载多少个程序员同时开发,访问 ...
- Nacos源码系列——第一章(Nacos核心源码主线剖析上)
在讲具体的源码之前,我有几点想说明下,很多开发可能觉得源码不重要,甚至觉得互联网 的知识,目前够用就可以,也不需要多么精通.的确,在大多数的公司中,你能用你的知识 解决问题就可以,不一定非要涉及到源码 ...
- 二、Neo4j源码研究系列 - 单步调试
二.Neo4j源码研究系列 - 单步调试 一.背景介绍 上一篇我们已经把了neo4j的源码准备以及打包流程完成了,本篇将讲解如何对neo4j进行单步调试.对于不了解如何编译打包neo4j的读者,请阅读 ...
- 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...
老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...
- 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1...
老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例 在上一节的第一个"增加日记"的示例中,我们并没有看到日记 ...
- 老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1...
老李推荐: 第8章4节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-启动AndroidDebugBridge 上一节我们看到在启动AndroidDebugBri ...
- idea 线程内存_Java线程池系列之-Java线程池底层源码分析系列(二)
课程简介: 课程目标:通过本课程学习,深入理解Java线程池,提升自身技术能力与价值. 适用人群:具有Java多线程基础的人群,希望深入理解线程池底层原理的人群. 课程概述:多线程的异步执行方式,虽然 ...
最新文章
- 服务器信息采集协议,服务器信息采集
- 这家公司不要求996,但照样市值万亿!
- c 程序 实现一元二次方程
- pandas 聚合函数
- 在一个工程(包)下面让activity和SensorEventListener监听分离,在不同类中完成
- 笔记本html外接显示器,笔记本如何外接显示器
- java标识符的介绍_Java标识符所有关键字
- NOI2018网络同步赛爆零记
- python根据url链接下载文件
- inside MPQ
- Primitive Function 归一化方向角
- 关于弱电间和机房的综合布线
- VM options常用设置
- 非真,亦非假——20世纪数学悖论入侵机器学习
- 用户画像标签系统体系解释
- 【python作品分享】计算器1.0
- 使用Element的 InfiniteScroll 无限滚动组件报错
- iptables企业面试题集锦
- 形象设计专业AR虚拟仿真实训方案
- OpenAI发布通用人工智能路线图:AGI比想象中来得更快