テスト環境 go version go1.7.3 windows/amd64
デフォルトの容量
golangのmap容量を拡張時に元データコッピーと再ハッシュが行うため
mapを作成時に容量を設定するほうがいいです。
package main
import "testing"
func test(m map[int]int) {
for i := 0; i < 10000; i++ {
m[i] = i
}
}
func BenchmarkMap(b *testing.B) {
for i := 0; i < b.N; i++ {
b.StopTimer()
m := make(map[int]int)
b.StartTimer()
test(m)
}
}
func BenchmarkCapMap(b *testing.B) {
for i := 0; i < b.N; i++ {
b.StopTimer()
m := make(map[int]int, 10000)
b.StartTimer()
test(m)
}
}
value vs pointer
package main
import (
"runtime"
"time"
)
const capacity = 500000
var d interface{}
func value() interface{} {
m := make(map[int]int, capacity)
for i := 0; i < capacity; i++ {
m[i] = i
}
return m
}
func pointer() interface{} {
m := make(map[int]*int, capacity)
for i := 0; i < capacity; i++ {
v := i
m[i] = &v
}
return m
}
func main() {
//GC走る時間のはmao key/valueほうがmap key/pointerにより早い
//でも大valueは多き(struct対象など)場合はkey/pointerが進めです
d = value() // d = pointer()
for i := 0; i < 20; i++ {
runtime.GC()
time.Sleep(time.Second)
}
}
テスト結果:(GCの時間を比べてください)
value関数を利用する場合:
pointer関数を利用する場合:
mapとメモリ空間
package main
import (
"runtime/debug"
"time"
)
const capacity = 1000000
var dict = make(map[int][100]byte, capacity)
func test() {
//データ追加
for i := 0; i < capacity; i++ {
dict[i] = [100]byte{}
}
//データ削除 (メモリ解放しません)
for k := range dict {
delete(dict, k)
}
dict = nil //メモリ空間解放
}
func main() {
test()
for i := 0; i < 20; i++ {
debug.FreeOSMemory()
time.Sleep(time.Second)
}
}