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 ...
随机推荐
- Leetcode 136 Single Number 仅出现一次的数字
原题地址https://leetcode.com/problems/single-number/ 题目描述Given an array of integers, every element appea ...
- Baidu地图Map api直接加https不起作用
这种情况一般出现在v1.1等老版本上,加s=1也不起作用,尽量使用新版本. https://api.map.baidu.com/api?v=2.0&ak=你的密钥&s=1:
- treap基本操作
利用rand保持堆的特性 const int N=; int ls[N],rs[N],v[N],p[N],cnt[N],siz[N]; // 权值 优先级 inline void update(int ...
- Filter Authentication 登录认证
[编程式配置]可用webxml配置替换@WebListenerpublic class FilterListenerConfigurator implements ServletContextList ...
- Andrew NG 机器学习编程作业4 Octave
问题描述:利用BP神经网络对识别阿拉伯数字(0-9) 训练数据集(training set)如下:一共有5000个训练实例(training instance),每个训练实例是一个400维特征的列向量 ...
- IHTMLDocument2类的使用
class Program { static void Main(string[] args) { SHDocVw.ShellWindows s ...
- Bootstrap响应式导航
<nav class="navbar navbar-default" role="navigation"> <div class=" ...
- Vue学习第一天:Vue.js指令系统
1. 如何使用Vue.js? 1.1 直接引入 - <script src="./statics/vue.min.js"></script> - 引入之后在 ...
- artTemplate/template.js模板将时间戳格式化为正常的日期
1:引用<script type="text/javascript" src="../js/artTemplate/template.js">< ...
- Hadoop之HDFS思维导图