【Go】Map 的空间利用率统计

Go 中 map 利用率

今天刷 B 站看见有 Up 主在讲布隆过滤器,提到了利用率的问题,假设有一组数据,范围分布非常广,使用布隆过滤器时如何尽量少的减少内存使用,感觉除了针对特定数据的定向优化外没什么特别好的办法,类似于 Google 那种加数据头以跳过大段间隙那样。然后想到类似的问题应该广泛存在于所有使用哈希表的数据结构中,那 go 中 map 的利用率如何呢?

数据收集

在 go 中 map 是一个内置的数据结构,没有一个简单的方法来拿到它占用的内存,以下两种方法供参考:

pprof

通过 pprof 定向收集内存分配和使用,我们可以直观的得到某个函数占用了多少内存:

package main
import ("net/http"_ "net/http/pprof"
)func demo() {n := 90000m := make(map[int64]int64)for i := 0; i < n; i++ {m[int64(i)] = int64(i)}for {}
}func TestSize(t *testing.T) {go func() {http.ListenAndServe(":3390", nil)}()demo()
}

然后通过 go tool pprof -http :9090 http://127.0.0.1:3390/debug/pprof/heap 观察 demo 的内存使用情况就可以了:

                                         2468.70kB   100% |   github.com/520MianXiangDuiXiang520/MapSize.TestSize /Users/junebao/Project/MapSize/mapsize_test.go:23 (inline)2468.70kB 40.77% 83.09%  2468.70kB 40.77%                | github.com/520MianXiangDuiXiang520/MapSize.demo /Users/junebao/Project/MapSize/mapsize_test.go:13

如上,我们就可以知道九万个 int64 的键值对占用了 2468.70KB

上面的办法简单粗暴,但要统计起来很麻烦

unsafe

我们知道 map 的底层结构其实是 runtime_hmap 那通过 unsafe 理论上就可以强转得到原始结构,只要知道了数据桶和溢出桶的个数,我们也可以计算出 map 的真实内存:

func Size[K comparable, V any](m map[K]V) int64 {var zeroK Kvar zeroValue VkeySize := unsafe.Sizeof(zeroK)valueSize := unsafe.Sizeof(zeroValue)vo := reflect.ValueOf(m)hm := (*hmap)(unsafe.Pointer(vo.Pointer()))bn := 1<<hm.B + uintptr(hm.noverflow)bz := unsafe.Sizeof(bmap{}) + (keySize+valueSize)*bucketCntreturn int64(unsafe.Sizeof(hmap{}) + bz*bn)
}

这个方法的缺点在于数值不精确,一来是 noverflow 是一个统计值,某些情况下可能会导致得到的溢出桶数量略小于真实数量,二来 bmap 中的 overflow 指针会根据键值对的类型有所变化,上面的程序中并没有计算该字段,因为键值对都不包含指针,理论上 map 会使用 hmap 的拓展字段存储溢出指针,总体来说该方法得到的值会小于真实值,但作为参考足够。如同样的九万个键值对使用上面方法得到的大小是 2457.976KB 比 pprof 版本少了 11KB

统计

func main() {for i := 0; i < 1000; i++ {n := i * 100m := make(map[int64]int64)for i := 0; i < n; i++ {m[int64(i)] = int64(i)}res := Size(m)t := int64(16 * n)fmt.Printf("%d,%d,%d,%d,%f\n", n, res, t, res-t, float64(t)/float64(res))}
}

以 100 为 步幅测试一千组用例,导入 CSV 用 python 绘制出图表:

import matplotlib.pyplot as plt
import csvclass MapSizeStatistic:"""A statistic of map storage usage in go where key-value pairs are all int64"""def __init__(self):self.utilization_list = []with open("./int64.csv") as fp:reader = csv.reader(fp)self.utilization_list = [float(i[-1]) for i in reader]print(self.utilization_list)def draw_utilization(self):x = [i*100 for i in range(len(self.utilization_list))]plt.plot(x, self.utilization_list)plt.show()if __name__ == '__main__':mss = MapSizeStatistic()mss.draw_utilization()

结果如下:

将键全部使用随机数,得到结果如下:

几乎没有差别,周期性变化非常明显,可以确定引起利用率变化的主要原因在于元素数量,而利用率突然降低的节点就是发生了等量扩容。

从上面的测试可以看到最高利用率在 0.8 左右,最低利用率只有 0.4, 平均只有 0.5 左右

总结

总体利用率在 50% 左右,主要影响因素在于等量扩容,虽然 map 本就是空间换时间,但如果确实需要优化并且走投无路时,希望这些数据或许可以提供一些参考(分片,卡利用率的点……)

最后放上一张合影:

代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ap模式和sta模式共存_AP+AC组网下的本地转发及集中转发

现在越来越多的企业都有自己的无线网络&#xff0c;而无线网络的组网方式一般都是使用ACAP模式进行组网&#xff0c;使用无线网络能够提供经济、高效的网络接入方式。相比有线网络&#xff0c;无线网络下只要能接入无线网的地方都可以使用网络&#xff0c;用户可以自由移动。而…

【干货分享】流程DEMO-事务呈批表

流程名&#xff1a; 事务呈批表 业务描述&#xff1a; 办公采购、会议费用等事务的申请。流程发起时&#xff0c;会检查预算&#xff0c;如果预算不够&#xff0c;将不允许发起费用申请&#xff0c;如果预算够用&#xff0c;将发起流程&#xff0c;同时占用相应金额的预算&…

【译】TcMalloc: Thread-Caching Malloc

TcMalloc 的核心是分层缓存&#xff0c;前端没有锁竞争&#xff0c;可以快速分配和释放较小的内存对象&#xff08;一般是 256 KB&#xff09;前端有两种实现&#xff0c;分别是 pre-CPU 和 pre-Thread 模式&#xff0c;前者申请一块大的连续内存&#xff0c;每一个逻辑 CPU 将…

kotlin编译失败_Kotlin使用GraalVM开发原生命令行应用

背景之前用kotlin开发过一款根据建表DDL语句生成plantuml ER图的应用。被问如何使用&#xff0c;答曰"给你一个jar包&#xff0c;然后执行java -jar ddl2plantuml.jar ./ddl.sql ./er.puml 就可以了。是不是so easy?"结果被吐槽了一番&#xff0c;为什么不能像命令行…

Swift - 添加纯净的Alamofire

Swift - 添加纯净的Alamofire 如果你有代码洁癖,不能容忍任何多余的东西,请继续往下看. 1. 下载Alamofire (https://github.com/Alamofire/Alamofire) 2. 解压缩并打开 Alamofire.xcworkspace 3. 删除不必要的内容 (根据你的需求自己定) 4. 顺便把文件夹里面的无关内容也删除掉…

jquery 获取系统默认年份_你没有看错,爬网页数据,C# 也可以像 Jquery 那样

一&#xff1a;背景1. 讲故事前段时间搞了一个地方性民生资讯号&#xff0c;资讯嘛&#xff0c;都是我抄你的&#xff0c;你抄官媒的&#xff0c;小市民都喜欢奇闻异事&#xff0c;所以就存在一个需求&#xff0c;如何去定向抓取奇闻异事的地方号上的新闻&#xff0c;其实做起来…

undertow 怎么创建线程_为什么很多SpringBoot开发者放弃了Tomcat,选择了Undertow

点击上方“后端技术精选”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;阿迈达toutiao.com/a6775476659416990212/前言在SpringBoot框架中&#xff0c;我们使用最多的是Tomcat&#xff0c;这是SpringBoot默认的容器技术&#xff0c;而且是内…

一起玩转CoordinatorLayout

作为Material Design风格的重要组件,CoordinatorLayout协调多种组件的联动&#xff0c;实现各种复杂的效果&#xff0c;在实际项目中扮演着越来越重要的角色。本篇博客将由浅到深&#xff0c;带你一起玩转CoordinatorLayout。 官方文档对CoordinatorLayout是这样描述的&#xf…

离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...

下面的链接是精华版思路&#xff0c;亮点是对第六问的探讨。高度概括一下&#xff1a;第一问曼哈顿&#xff0c;第二问用免疫&#xff0c;三问增加任务单&#xff0c;四问增加拣货员&#xff0c;五问改变复核台&#xff0c;六问亮点来探讨~ 有点皮MathorCup C题 仓内拣货优化问…

【VBA编程】10.自定义集合

自定义集合类型&#xff0c;类似于变量声明&#xff0c;只是要将Dim关键字和New collection关键字搭配起来使用&#xff0c;其语法描述如下&#xff1a;其中集合名的命名方式同于标准变量的命名 Dim 集合名 As New collection 对于已经定义的集合对象&#xff0c;可以使用集合的…

git fork clone 区别_Working with Git | Git 与 GitHub

关于各位好&#xff0c;这里是 Chinas Prices Project 项目的知乎专栏。关于 CPP 项目&#xff0c;您可以在这篇文章里了解到更多的信息。若您对这个项目感兴趣&#xff0c;我们非常欢迎您与我们交流您的想法与见解。在一个团队的成员同时为一个项目进行开发工作时&#xff0c;…

舒适的路线(codevs 1001)

题目描述 DescriptionZ小镇是一个景色宜人的地方&#xff0c;吸引来自各地的观光客来此旅游观光。Z小镇附近共有N(1<N≤500)个景点&#xff08;编号为1,2,3,…,N&#xff09;&#xff0c;这些景点被M&#xff08;0<M≤5000&#xff09;条道路连接着&#xff0c;所有道路都…

PHP_Smarty

模板 数据与表现层的标签分离 smarty是PHP 与 HTML代码的分离 小型模板类 $smarty 的工作流程&#xff1a; 把需要显示的全局变量&#xff0c;赋值塞到对象内部的属性上&#xff0c;一个数组中.编译模板&#xff0c;把{$标签},解析成相应的<?php echo 代码引入编译后的PHP文…

读中文_挑战来了!康辉喊你读中文十级绕口令!

文章来源&#xff1a;央视频汉语桥木甬读桶不读涌&#xff0c;月农读脓不读胧。米更读粳不读梗&#xff0c;日青读晴不读睛。米宗读粽不读综&#xff0c;言丁读订不读钉。土竟读境不是镜&#xff0c;土平读坪不是评。耳令读聆不读岭&#xff0c;火登读灯不读澄。言甬读诵不读蛹…

ios 自定义键盘

由于项目需要&#xff0c;需要自定义键盘。ios系统键盘会缓存键盘输入&#xff0c;并保存在系统目录下的文件里&#xff0c;并且是明文存储&#xff0c;存在帐号密码泄漏风险。在别人代码基础上修改了下&#xff0c;美化了下界面&#xff0c;去掉了字符输入&#xff0c;加了点击…

【GOF23设计模式】迭代器模式

【GOF23设计模式】迭代器模式 来源&#xff1a;http://www.bjsxt.com/ 一、【GOF23设计模式】_迭代器模式、JDK内置迭代器、内部类迭代器 1 package com.test.iterator;2 /**3 * 自定义的迭代器接口4 */5 public interface MyIterator {6 void first(); //将游标指向第…

51单片机50个实例代码_【附代码】51单片机电子密码锁教程

简介大家好&#xff0c;这篇文章的内容是关于如何用51单片机来制作一个电子密码锁的教程&#xff0c;通过这篇教程可以让刚入门的朋友了解矩阵键盘、LCD1602的使用方法&#xff0c;以及密码输入和修改的程序介绍&#xff0c;我会对每个部分进行详细的介绍。首先我们来看一下这个…

8数据提供什么掩膜产品_博硕能为你提供什么产品?

自动喷漆设备应用于线条、木门、橱柜、楼梯、套房家具、办公家具、木饰面板、外墙保温装饰一体板板等产品领域&#xff0c;针对NC、PU、UV、水性漆和氟碳漆等不同种类的油漆&#xff0c;进行自动化喷涂和干燥作业。自动喷漆设备有多种规格型号&#xff0c;分为不同的喷涂方式。…

jsp页面验证码(完整实例)

项目结构如下&#xff0c;MyEclipse中新建一个Web Project&#xff0c;取名servlet 1、src下new一个servlet类 package com.servlet;import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOExcept…

开源oa_圈子哥推荐一款基于 Spring Boot 开发 OA 开源产品,学习/搞外快都是不二选择!...

点击上方蓝字关注「程序员的技术圈子」今天圈子哥给大家推荐一套Spring Boot 开发 OA系统&#xff0c;系统功能齐全&#xff0c;不管是用来学习或者搞外快都是不错的选择&#xff0c;clone下来吧&#xff01;办公自动化(OA)是面向组织的日常运作和管理&#xff0c;员工及管理者…