[WIL] zero-allocation

yoonn·2024년 2월 28일
post-thumbnail

Zero allocation?

  • 힙 영역에 대한 동적 메모리 할당을 줄이는 것
  • 메모리 할당과 해제에 따른 오버헤드를 줄여 성능을 향상시킴.

활용

  • map, slice 등을 사용할 때 미리 size를 지정
  • 생성한 map, slice 등을 초기화하여 재사용
  • strings.Builder 사용
    - 내부적으로 buffer를 재사용
  • struct{} (빈 struct)

등등..

실습

소스코드: https://github.com/yoon1/wil/tree/main/zero-allocation

Go에서 memory 측정하는 법

이 포스트에서는 benchmark로 확인했음.

without zero-allocation

func withoutZeroAllocation() {
	var slice []int
	for i := 0; i < 1000000; i++ {
		slice = append(slice, i)
	}
}

with zero-allocation

func withZeroAllocation() {
	array := [1000000]int{}
	for i := 0; i < 1000000; i++ {
		array[i] = i
	}
}

benchmark test

func BenchmarkWithoutZeroAllocation(b *testing.B) {
	for i := 0; i < b.N; i++ {
		withoutZeroAllocation()
	}
}

func BenchmarkWithZeroAllocation(b *testing.B) {
	for i := 0; i < b.N; i++ {
		withZeroAllocation()
	}
}

run

 go test -bench . -benchmem
  • -benchmem : memory statistics

결과

BenchmarkWithoutZeroAllocation-10           3829            313277 ns/op               0 B/op          0 allocs/op
BenchmarkWithZeroAllocation-10               436           2709576 ns/op        41678186 B/op         39 allocs/op

without zero allocation string

func withoutZeroAllocationStr() string {
	var s string

	for n := 0; n < 1000000; n++ {
		s += "Hello"
		s += "World"
	}

	return s
}

with zero allocation string

func withZeroAllocationStr() string {
	var builder strings.Builder
	for n := 0; n < 1000000; n++ {
		builder.WriteString("Hello")
		builder.WriteString("World")
	}

	return builder.String()
}

benchmark test

benchmark code 및 실행 방법 위와 동일

결과

BenchmarkWithZeroAllocationStr-10                  15054             77785 ns/op          514810 B/op         24 allocs/op
BenchmarkWithoutZeroAllocationStr-10                  16          70046294 ns/op        1061959346 B/op    20043 allocs/op

Next

zero allocation을 활용한 package 살펴보기

Reference

0개의 댓글