golang切片分配性能

J. *_*Dow 5 memory performance 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) 
}
Run Code Online (Sandbox Code Playgroud)

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

J. *_*Dow 5

设置GOGC =关闭改进的性能(低至100ms).为什么?因为逃避分析.使用go build -gcflags -m编译器构建时,打印任何分配转义到堆.这实际上取决于你的机器和GO编译器版本,但是当编译器决定分配应该移动到堆时,它意味着两件事:1.分配将花费更长时间(因为在堆栈上"分配"只是1 cpu指令)2. GC将不得不在以后清理该内存 - 为我的机器花费更多的CPU时间,65536字节的分配转移到堆而65535不转移.这就是为什么1个字节将整个过程从200ms改为30s.惊人..