performance - golang slice 分配性能

标签 performance memory go

我在检查 GO 中内存分配的性能时偶然发现了一件有趣的事情。

package main

import (
      "fmt"
      "time"
    )

func main(){
   const alloc int = 65536
   now := time.Now()
   loop := 50000
   for i := 0; i<loop;i++{
      sl := make([]byte, alloc)
      i += len(sl) * 0
   }
   elpased := time.Since(now)
   fmt.Printf("took %s to allocate %d bytes %d times", elpased, alloc, loop) 
}

我在 Core-i7 2600 上运行它,go 版本 1.6 64 位(在 32 位上结果相同)和 16GB 内存(在 WINDOWS 10 上) 因此,当 alloc 为 65536(恰好 64K)时,它会运行 30 秒(!!!!)。 当 alloc 为 65535 时,它需要大约 200 毫秒。 有人可以向我解释一下吗? 我在家里用我的核心 i7-920 @ 3.8GHZ 尝试了相同的代码,但它没有显示相同的结果(都花了大约 200 毫秒)。有人知道发生了什么事吗?

最佳答案

设置 GOGC=off 可提高性能(降至不到 100 毫秒)。为什么? 因为escape analysis .当您使用 go build -gcflags -m 构建时,编译器会打印逃逸到堆中的任何分配。这真的取决于你的机器和 GO 编译器版本,但是当编译器决定分配应该移动到堆时,它意味着两件事: 1.分配将花费更长的时间(因为在堆栈上“分配”只是 1 个 cpu 指令) 2. GC 稍后将不得不清理该内存 - 花费更多的 CPU 时间 对于我的机器,65536 字节的分配逃逸到堆中,而 65535 字节则没有。 这就是为什么 1 个字节将整个过程从 200 毫秒更改为 30 秒。太棒了..

关于performance - golang slice 分配性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36125927/

相关文章:

performance - 使用存储过程是否有重大的性能提升?

python - Numpy:如何向量化应用于数据集的函数的函数形式的参数

performance - 通过 JDBC 调用 PL/SQL 包性能问题

c++ - 我怎么知道我上次的指示

go - 如何避免翻译一些 helm chart 的 `{{`?

ruby-on-rails - Ruby on Rails 迁移非常慢

ios - tmp目录下的文件删除后仍然占用空间ios

android - Android 何时给出 OutOfMemory 异常?

function - Golang 文档中 "a"之前的 "..."和 "interface{}"是什么意思?

mysql - 从 Go 连接到 MySQL 的推荐方式是什么?