总结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. laravel-v5.1分页并带参数

    控制器的代码中

  2. mongoDB系列之(二):mongoDB 副本集

    1. 什么是副本集 副本集就是mongoDB副本所组成的一个集群. 同期原理是,写操作发生在主库,从库同步主库的OpLog日志. 集群中没有特定的主库,主库是选举产生,如果主库down了,会再选举出一 ...

  3. LevelDB场景分析1--整体结构分析

    基本用法 数据结构 class DBImpl : public DB { private:     struct CompactionState;     struct Writer;// Infor ...

  4. cocos2dx 3.1从零学习(四)——内存管理(错误案例分析)

    本篇内容文字比較较多,可是这些都是建立在前面三章写代码特别是传值的时候崩溃的基础上的.可能表达的跟正确的机制有出入,还请指正. 假设有不理解的能够联系我.大家能够讨论一下,共同学习. 首先明白一个事实 ...

  5. 清理linux 某个文件夹下面所有的log文件

    #!/bin/sh #目标文件夹下面所有问题 target_dir="/app/" #删除2天前新建的后缀为log的文件 -name "*.log" -exec ...

  6. Matlab图形调色

    Matlab图形调色 Simple example var colormap = require('colormap') options = {   colormap: 'jet',   // pic ...

  7. Latex 附录生成方法-附使用的一些tips

    Latex 附录生成方法-附使用的一些tips 工具 使用latex写论文时,国内科研人员使用比较多的前端工具当属CTex,另外的前度工具有texstdio,texworks,sublime,甚至vi ...

  8. Leaf——美团点评分布式ID生成系统

    背景 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数 ...

  9. Centos设置静态IP及修改Centos配置文件的方法

    通常,如果我们想更改主机地址为静态地址或者更改主机名,需要修改的几个文件包括: /etc/sysconfig/network Centos设置主机名和网络配置 /etc/sysconfig/netwo ...

  10. 在 Windows 8 中启用可匿名访问的共享

    就是不用输入用户名和密码,直接通过网上邻居可以访问的共享. 1.打开本地组策略编辑器(快捷键Win+R,打开运行,输入gpedit.msc,确定): 2.打开:"本地计算机策略->计算 ...