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()
B.Set().Set()
for i := ; i < b.N; i++ {
if B.Exists() { }
if B.Exists() { }
if B.Exists() { }
}
} func BenchmarkMap(b *testing.B) {
var B = make(map[int]int8, )
B[] =
B[] =
for i := ; i < b.N; i++ {
if _, exists := B[]; exists { }
if _, exists := B[]; exists { }
if _, exists := B[]; exists { }
}
} BenchmarkIntSet- 35.3 ns/op B/op allocs/op
BenchmarkMap- 41.2 ns/op B/op allocs/op
结论
- 性能,有些提升,但不是特别明显。尤其是线上压力不大的情况性能应该不会有明显变化;
- 内存占用。我们的服务缓存较多、占用内存较大,通过这个优化实测可以减少 1.6 GB 的空间。不过这个优化的空间取决于数据量。
参考文献
- 【1】 The empty struct - Dave Cheney
- 【2】 gods - emirpasic
- 【3】 《Go 语言学习笔记》 - 雨痕。5.5 结构。
Golang 优化之路-空结构[转]的更多相关文章
- Golang 优化之路——bitset
写在前面 开发过程中会经常处理集合这种数据结构,简单点的处理方法都是使用内置的map实现.但是如果要应对大量数据,例如,存放大量电话号码,使用map占用内存大的问题就会凸显出来.内存占用高又会带来一些 ...
- golang | Go语言入门教程——结构体初始化与继承
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题第10篇文章,我们继续来看golang当中的面向对象部分. 在上一篇文章当中我们一起学习了怎么创建一个结构体,以及怎么 ...
- Golang面向对象编程-struct(结构体)
Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...
- CSS代码重构与优化之路(转)
CSS代码重构与优化之路 阅读目录 CSS代码重构的目的 CSS代码重构的基本方法 CSS方法论 我自己总结的方法 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多 ...
- Greenplum 性能优化之路 --(二)存储格式
一.存储格式介绍 Greenplum(以下简称 GP)有2种存储格式,Heap 表和 AO 表(AORO 表,AOCO 表). Heap 表:这种存储格式是从 PostgreSQL 继承而来的,目前是 ...
- 为什么C++中空类和空结构体大小为1?(转载)
原文链接:http://www.spongeliu.com/260.html 对于结构体和空类大小是1这个问题,首先这是一个C++问题,在C语言下空结构体大小为0(当然这是编译器相关的).这里的空类和 ...
- 微博MySQL优化之路--dockone微信群分享
微博MySQL优化之路 数据库是所有架构中不可缺少的一环,一旦数据库出现性能问题,那对整个系统都回来带灾难性的后果.并且数据库一旦出现问题,由于数据库天生有状态(分主从)带数据(一般还不小),所以出问 ...
- 新浪微博iOS客户端架构与优化之路
新浪微博iOS客户端架构与优化之路 随着Facebook.Twitter.微博的崛起,向UGC.PGC.OGC,自媒体提供平台的内 容消费型App逐渐形成了独特的客户端架构模式.与电商和通讯工具类 ...
- 转:为什么C++中空类和空结构体大小为1?
参考:http://www.spongeliu.com/260.html 为什么C++中空类和空结构体大小为1? On November 17, 2010, in C语言, 语言学习, by spon ...
随机推荐
- bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)
https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...
- 【自适应波束形成】MVDR(Minimum Variance Distortionless Response )笔记
参考: https://blog.csdn.net/qq_40981790/article/details/80143524 1. MVDR简介(Minimum Variance Distortion ...
- extern "C" 含义
extern "C" 被 extern 限定的函数或变量是 extern 类型的 被 extern "C" 修饰的变量和函数是按照 C 语言方式编译和链接的 e ...
- windows server 2008r2x64 安全配置
管理工具--本地安全策略 1.帐户策略--密码策略 密码长度最小值:8 强制密码历史:1 2.本地安全策略--安全选项 交互式登录:不显示最后的用户名:已启用
- react暴露webpack配置文件
在react中安装create-react-app脚手架新建项目,但是新建的项目中没有配置文件. webpack的配置文件webpack.base.conf.js隐藏在了node_modules文件夹 ...
- 015、调试Dockerfile(2019-01-04 周五)
参考https://www.cnblogs.com/CloudMan6/p/6853329.html Dockerfile构建镜像的过程 1.从base镜像运行一个容器 2.执行一条指令,对容 ...
- sql parser
最近在整理很多SQL代码, 需要分析出每个SQL的目标表和源表各有哪些, 网上没有找到工作具, 打算写个工具. Java调研结果:1. 商业组件包 sqlparser 有试用版组件, 限制SQL少于1 ...
- SQL的六种约束
https://blog.csdn.net/z120270662/article/details/79501621
- ios 不支持-,-时间。
var date = "2000-08-29"; console.log(new Date(date).getTime());解决办法 date .replace(/-/g, ' ...
- JS判断是电脑浏览器还是手机端浏览器,并根据不同的终端跳转到不同的网址
<!DOCTYPE html> <html> <script> function browserRedirect() { var sUserAgent = navi ...