strconv을 fmt보다 선호
원시 자료형을 문자열로 변환하거나 문자열을 원시 자료형으로 변환할 때 strconv
가 fmt
보다 빠릅니다.
비권장:
for i := 0; i < b.N; i++ {
s := fmt.Sprint(rand.Int())
}
권장:
for i := 0; i < b.N; i++ {
s := strconv.Itoa(rand.Int())
}
문자열을 바이트로 변환하지 않기
고정된 문자열에서 반복적으로 바이트 슬라이스를 만드는 것을 피하십시오. 대신 변환을 한 번 수행하고 결과를 보존하십시오.
비권장:
for i := 0; i < b.N; i++ {
w.Write([]byte("Hello world"))
}
권장:
data := []byte("Hello world")
for i := 0; i < b.N; i++ {
w.Write(data)
}
컨테이너 용량 지정
가능한 경우 컨테이너 용량을 지정하여 컨테이너에 메모리를 미리 할당하십시오. 이렇게 하면 요소를 추가할 때 컨테이너를 복사하고 크기를 조정하여 후속 할당을 최소화할 수 있습니다.
Map 용량 힌트
대부분의 경우 make()
로 초기화할 때 용량 정보를 제공하십시오.
make(map[T1]T2, 힌트)
make()
에 용량 힌트를 제공하면 요소를 추가할 때 메모리 재할당을 줄이기 위해 초기화시 맵의 크기를 조정합니다.
슬라이스와 달리 맵의 용량 힌트는 완전한 미리 할당을 보장하지는 않지만 해시맵 버킷 수를 추정하는 데 사용됩니다. 따라서 맵에 요소를 추가할 때도 할당이 발생할 수 있으며 맵 용량을 지정하더라도 런타임에 더 많은 할당이 될 수 있습니다.
비권장:
m := make(map[string]os.FileInfo)
files, _ := os.ReadDir("./files")
for _, f := range files {
m[f.Name()] = f
}
// m은 크기 힌트 없이 생성되었으므로 런타임에 더 많은 할당이 발생할 수 있습니다.
권장:
files, _ := os.ReadDir("./files")
m := make(map[string]os.FileInfo, len(files))
for _, f := range files {
m[f.Name()] = f
}
// m은 크기 힌트로 생성되었으므로 런타임에 더 적은 할당이 발생할 수 있습니다.
슬라이스 용량 지정
대부분의 경우 make()
를 사용하여 슬라이스를 초기화할 때 용량 정보를 제공하십시오. 특히 슬라이스에 추가하는 경우에는 더욱 중요합니다.
make([]T, 길이, 용량)
맵과 달리 슬라이스 용량은 단순히 힌트가 아닙니다. make()
에서 제공된 슬라이스 용량에 대해 컴파일러가 충분한 메모리를 할당하므로 후속 append()
작업은 제로 할당으로 결과가 나올 것입니다(슬라이스의 길이가 용량과 일치할 때까지, 추가로 할당이 발생하면 요소를 수용하기 위해 크기를 재조정할 수 있습니다).
비권장:
for n := 0; n < b.N; n++ {
data := make([]int, 0)
for k := 0; k < size; k++{
data = append(data, k)
}
}
권장:
for n := 0; n < b.N; n++ {
data := make([]int, 0, size)
for k := 0; k < size; k++{
data = append(data, k)
}
}