Golang 优化之路-空结构[转]
写在前面
开发 hashset 常用的套路:
map[int]int8
map[int]bool
我们一般只用 map 的键来保存数据,值是没有用的。所以来缓存集合数据会造成内存浪费。
空对象
空对象是个神奇的东西。它指的是没有字段的结构类型。
type Q struct{}
它牛逼的地方在于:
可以和普通结构一样操作
var a = []struct{}{struct{}{}} fmt.Println(len(a)) // prints 1
不占用空间
var s struct{} fmt.Println(unsafe.Sizeof(s)) // prints 0
声明两个空对象,它们指向同一个地址
type A struct{} a := A{} b := A{} fmt.Println(&a == &b) // prints true
造成这个结果的原因是 Golang 的编译器会把这种空对象都当成 runtime.zerobase
处理。
var zerobase uintptr
hashset
有了上面的介绍,就可以利用空结构来优化 hashset 了。
var itemExists = struct{}{}type Set struct {items map[interface{}]struct{} }func New() *Set {return &Set{items: make(map[interface{}]struct{})} }func (set *Set) Add(item interface{}) {set.items[item] = itemExists }func (set *Set) Remove(item interface{}) {delete(set.items, item) }func (set *Set) Contains(item interface{}) bool {if _, contains := set.items[item]; !contains {return false}return true }
一个简易的 hashset 实现就完成了。
性能比较
func BenchmarkIntSet(b *testing.B) {var B = NewIntSet(3)B.Set(10).Set(11)for i := 0; i < b.N; i++ {if B.Exists(1) {}if B.Exists(11) {}if B.Exists(1000000) {}} }func BenchmarkMap(b *testing.B) {var B = make(map[int]int8, 3)B[10] = 1B[11] = 1for i := 0; i < b.N; i++ {if _, exists := B[1]; exists {}if _, exists := B[11]; exists {}if _, exists := B[1000000]; exists {}} }BenchmarkIntSet-2 50000000 35.3 ns/op 0 B/op 0 allocs/op BenchmarkMap-2 30000000 41.2 ns/op 0 B/op 0 allocs/op
结论
- 性能,有些提升,但不是特别明显。尤其是线上压力不大的情况性能应该不会有明显变化;
- 内存占用。我们的服务缓存较多、占用内存较大,通过这个优化实测可以减少 1.6 GB 的空间。不过这个优化的空间取决于数据量。
参考文献
- 【1】 The empty struct - Dave Cheney
- 【2】 gods - emirpasic
- 【3】 《Go 语言学习笔记》 - 雨痕。5.5 结构。
转载于:https://www.cnblogs.com/logo-fox/p/6985598.html
Golang 优化之路-空结构[转]相关推荐
- Golang 优化之路——HTTP长连接
压测发现有长连接问题,深入学习了一下. 写在前面 TCP 相关 HTTP 包如何使用 TCP 长连接? 我们的程序为啥长连接失效? 如何解决问题? 后续 参考文献 写在前面 压测的是否发现服务端TIM ...
- golang怎么给空结构体赋值
一.前言 最近没少使用golang,也没经过系统的学习,直接就上去开发了,遇到不少坑也学到不少东西,本次记录下给空结构体赋值的问题. 二.案例 1.结构体结构及错误 type Test struct ...
- Golang之空结构体和零长数组的实践
空结构体和零长数组(两个复合类型)都仅仅是一个占位符,不占用空间,这里编译器进行了优化,如果结构体或数组的unsafe.sizeof=0则直接返回zerobase. // 必须用key来初始化结构体 ...
- Go 空结构体的 3 种使用场景
转子地址:https://mp.weixin.qq.com/s/zWzyl6x9sZdXZCaAuva2lA 在 Go 语言中,有一个比较特殊的类型,经常会有刚接触 Go 的小伙伴问到,又或是不理解. ...
- 懂球帝Android客户端WebView优化之路
导读 本文作者:涂晓龙 发布时间:2019-12-09 原文地址:https://mp.weixin.qq.com/s/MtEi6DgrNCO6HB2eQ0uBrw 这篇文章讲的是懂球帝Android ...
- 蚂蚁金服服务注册中心 SOFARegistry 解析 | 服务发现优化之路
SOFAStack Scalable Open Financial Architecture Stack 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景 ...
- CSS代码重构与优化之路(转)
CSS代码重构与优化之路 阅读目录 CSS代码重构的目的 CSS代码重构的基本方法 CSS方法论 我自己总结的方法 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多,如 ...
- go语言-空结构体/ chan struct{}
文章目录 空结构体 struct{} chan struct{} 常用用法 带缓冲的chan struct{}数据读写 空结构体 struct{} 空结构体的宽度是0,占用了0字节的内存空间. var ...
- Golang 优化之内存对齐
这里填写标题 1. Golang 优化之内存对齐 1.1. 前文 1.2. 正文 1.2.1. 什么是内存对齐? 1.2.2. 为什么需要内存对齐? 1.2.2.1. 平台原因 1.2.2.2. 性能 ...
最新文章
- 在django中区分null = True,空白= True
- 控制ALV单元格可编辑
- 计算机一级115,计算机一级BASIC模拟115.doc
- 19.内在摄像机校准——内联函数 测验,结合外在和内在校准参数,编写相同方程的其他方法,相机参数_2
- 微信头像失效_如何判断微信授权的头像是否失效
- 微信小程序点餐系统怎么做
- 程序设计题大病:劝你不要买未来教育的Python二级书
- Qt网络编程之获取网络信息
- 电路板上的这些标志你都知道是什么含义吗?——详解电子产品认证类型
- JspStudy套件部署j2ee maven项目网址问题
- Tomcat8.5访问HTML页面出现乱码
- 哪种pdf编辑器更方便使用
- selenium+python+eclipse 实现 “问卷星”网站,登录与检查登录示例!
- 小程序和服务器之间的通信,微信小程序建立服务器通信的方法
- php正则保留字母数字,php正则只保留汉字字母数字
- 从中序与后序遍历序列构造二叉树
- R平方值python实现
- 流行手机谜语大解密 (爱情诗)
- 少儿Python视频课程A级简介
- ubuntu安装ActiveMQ