memory - 最小化 go map 的内存分配

标签 memory optimization go

我目前正在深入研究如何优化 go 中一些频繁使用的代码。我的问题归结为以下代码片段(从 pprof list 命令复制了内存分配)。如您所见,所有分配都在填充 map 的行中完成(第 959 行)。

ROUTINE ======================== cart.BenchmarkMapWithOutCapacityFixVal in /.../cart_test.go
   3328966    3328966 (flat, cum) 15.50% of Total
         .          .    954:
         .          .    955:func BenchmarkMapWithOutCapacityFixVal(b *testing.B) {
         .          .    956:   for i := 0; i < b.N; i++ {
         .          .    957:       m := make(map[int]float32)
         .          .    958:       for k := 0; k < 10; k++ {
   3328966    3328966    959:           m[k] = 0.434295723423
         .          .    960:       }
         .          .    961:   }
         .          .    962:}

这是我正在尝试做的事情:我正在尝试在(内部)循环之前分配内存,这样就不会发生不必要的分配:

ROUTINE ======================== cart.BenchmarkMapWithCapacityFixVal in /.../cart_test.go
   3214263    3214263 (flat, cum) 14.97% of Total
         .          .    963:
         .          .    964:func BenchmarkMapWithCapacityFixVal(b *testing.B) {
         .          .    965:   for i := 0; i < b.N; i++ {
   3048075    3048075    966:       m := make(map[int]float32, 10)
         .          .    967:       for k := 0; k < 10; k++ {
    166188     166188    968:           m[k] = 0.434295723423
         .          .    969:       }
         .          .    970:   }
         .          .    971:}

为什么在第 968 行(第二个示例)中仍然发生分配,我如何才能在内循环之前正确分配映射?

最佳答案

map 不是数组。您无法在其中预先分配空间,因为您不知道元素将插入 map 中的哪个位置。在 make(map..., X) 中,X 只是一个容量hint,它不绑定(bind) map 并且绝对不能保证 key 将完美散列进去。因此,它将尽最大努力减少 future 分配的数量,但没有办法消除所有分配。

在这个特定的例子中,如果你想完美地控制分配,你应该只使用数组而不是映射。使用适当的数组,您将只有一个分配。

关于memory - 最小化 go map 的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38095210/

相关文章:

linux - Linux中套接字的内存消耗和压缩行为

memory - CUDA 表面与纹理

mysql - 使用 or 条件进行内连接

optimization - 如何用PHP实现服务器端缓存

.net - 分析进程中加载​​的 native DLL 和程序集的内存占用的工具?

c++ - vector<string> 超出范围后不清除内存

mysql - 如何显示SQL查询的访问路径

json - 使用 Echo 测试 POST 请求(预期输出与实际输出)

go - 在VS Code中调试时如何评估表达式?

golang 从 stdin 读取长文本