总结golang之map

2017年04月13日 23:35:53 趁年轻造起来 阅读数:18637 标签: golangmapgo 更多

个人分类: golang
 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Soooooooo8/article/details/70163475

0x01 map基本操作

  • 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

0x02 map键类型

支持 == 操作符的类型有:

  • boolean,
  • numeric,
  • string,
  • pointer,
  • channel,
  • interface(as long as dynamic type supports equality),
  • 以及只包含上述类型的array和struct

不支持 == 操作符的类型有:

  • slice,
  • map,
  • func,

补充

  1. 不像Java可以为class自定义hashcode方法,以及C++可以重载==操作符,golang map**不支持**==重载或者使用自定义的hash方法。因此,如果想要把struct用作map的key,就必须保证struct不包含slice, map, func
  2. golang为uint32、uint64、string提供了fast access,使用这些类型作为key可以提高map访问速度,详见hashmap_fast.go

0x03 map并发

map不是并发安全的,通常使用sync.RWMutex保护并发map

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

0x04 map小技巧

4.1. 利用value类型的零值

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.2. map[k1]map[k2]v 对比 map[struct{k1, k2}]v

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

0x05 map实现细节浅析

5.1. 如何计算hash值

golang为每个类型定义了类型描述器_type,并实现了hashable类型的_type.alg.hash_type.alg.equal

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.2. map实现结构

map的实现主要有三个struct,

  1. maptype用来保存map的类型信息,包括key、elem(value)的类型描述器,keysize,valuesize,bucketsize等;
  2. hmap - A header for a Go map. hmap保存了map的实例信息,包括count,buckets,oldbuckets等;buckets是bucket的首地址,用hash值的低h.B位hash & (uintptr(1)<<h.B - 1)计算出key所在bucket的index; 
  3. bmap - A bucket for a go map. bmap只有一个域tophash [bucketCnt]uint8,它保存了key的hash值的高8位uint8(hash >> (sys.PtrSize*8 - 8));一个bucket包括一个bmap(tophash数组),紧跟的bucketCnt个keys和bucketCnt个values,以及一个overfolw指针。 

makemap根据maptype中的信息初始化hmap

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.3. 如何访问map

golang的maptype保存了key的类型描述器,以供访问map时调用key.alg.hashkey.alg.equal

  • 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
  • 42

5.4. map扩张

这部分留待以后有机会再续。这里暂时附上Keith Randall的slide作为参考。 

0x06 map建议

  • 如果知道size,预先分配资源make(map[int]int, 1000)
  • uint32, uint64, string作为键,非常快
  • 清理map:for k:= range m { delete(m, k) }
  • key和value中没有指针可以使GC scanning更快

总结golang之map的更多相关文章

  1. Golang中map的三种声明方式和简单实现增删改查

    package main import ( "fmt" ) func main() { test3 := map[string]string{ "one": & ...

  2. golang 中 map 转 struct

    golang 中 map 转 struct package main import ( "fmt" "github.com/goinggo/mapstructure&qu ...

  3. golang之map的使用声明

    1.map的基本介绍 map是key-value数据结构,又称为字段或者关联数组.类似其它编程语言的集合,在编程中是经常使用到的 2.map的声明 1)基本语法 var map 变量名 map[key ...

  4. Golang:sync.Map

    由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...

  5. golang中map原理剖析

    1. golang中的map有自己的一套实现原理,其核心是由hmap和bmap两个结构体实现的 2.  初始化map package main func main() { // 初始化一个可容纳10个 ...

  6. golang笔记——map

    通过 new 创建的引用类型对象是不完整创建,比如 map,它仅分配了字典类型本身所需的内存(指针包装),而没有分配键值存储内存,也没有初始化散列桶等内部属性,因此无法工作,如下代码就是错误的: p ...

  7. 【GoLang】GoLang 遍历 map、slice、array方法

    代码示例: map1 := make(map[string]string) map1["a"] = "AAA" map1["b"] = &q ...

  8. Golang 嵌套map赋值办法

    http://my.oschina.net/sol/blog/159060 m := map[string]map[string]string{} mm, ok := m["kkk" ...

  9. golang的map

    map--字典 map的基本使用: package main import "fmt" // 先声明 type PersonInfo struct { id string name ...

随机推荐

  1. IE浏览器中,设置指定程序查看源文件

    第一步:     先按Ctrl+R,输入regedit进入注册表     依次找到 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explo ...

  2. python学习笔记013——模块中的私有属性

    1 私有属性的使用方式 在python中,没有类似private之类的关键字来声明私有方法或属性.若要声明其私有属性,语法规则为: 属性前加双下划线,属性后不加(双)下划线,如将属性name私有化,则 ...

  3. C#:小写金额转换为大写

    #region 小写金额转换为大写 public static string CurrToChnNum(double Currnum) { string sResult = ""; ...

  4. 套接字I/O超时设置方法和用select实现超时

    注:如无特殊说明,sockfd 原始状态都是阻塞的. 一.使用alarm 函数设置超时  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 13   void handler( ...

  5. [转]VTH changes in DC from Hspice

    Hello, everyone. I’d like to know the threshold of the MOS transistor. And I found the “.print vth() ...

  6. Spring 中属性配置

    1 注册自定义属性编辑器,方法一.使用BeanFactory, 则用户需要手动调用 registerCustomEditor(Class requiredType, PropertyEditor pr ...

  7. php的安装

    首先我们安装nginx #0.安装ningx(可选cd /disk1/toolsrpm -ivh  http://nginx.org/packages/centos/6/noarch/RPMS/ngi ...

  8. 数据库分享一: MySQL的Innodb缓存相关优化

    无论是对于哪一种数据库来说,缓存技术都是提高数据库性能的关键技术,物理磁盘的访问速度永 远都会与内存的访问速度永远都不是一个数量级的.通过缓存技术无论是在读还是写方面都可以大大提 高数据库整体性能. ...

  9. ps减去图层混合模式

    ps减去图层混合模式 CMYK 1.1.青色作为基色,品红作为混合色(减去混合模式) 红反即青色(绿色+蓝色) - 绿反即品红色(红色+蓝色)= 绿色   公式简化: 绿色 + 蓝色 - 红色 - 蓝 ...

  10. 漂亮的Qt控件 QSS代码例子

    Qt Style Sheets Examples We will now see a few examples to get started with using Qt Style Sheets. S ...