golang - 성능 조사 map과 GC
테스트 환경: 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가 동작하는 시간은 map 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)
}
}
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)
}
}
dict = nil 을 하지 않은 경우
dict = nil 하는 경우
출처: http://qiita.com/oywc410/items/ad8baee00f039705a5c0
이 글은 2018-05-25에 작성되었습니다.