skip to content
Alvin Lucillo

Basic memory benchmarking

/ 2 min read

For today and upcoming daily entries, we will discuss benchmark with memory metrics with the two functions below.

Both BuildMessageBatchGrowing and BuildMessageBatchPreallocated iterates a 2d array and collects them, but notice that the latter allocates the total bytes first before collecting the values.

func BuildMessageBatchGrowing(messages [][]byte) []byte {
	var batch []byte
	for _, message := range messages {
		batch = append(batch, message...)
	}
	return batch
}

func BuildMessageBatchPreallocated(messages [][]byte) []byte {
	totalBytes := 0
	for _, message := range messages {
		totalBytes += len(message)
	}

	batch := make([]byte, 0, totalBytes)
	for _, message := range messages {
		batch = append(batch, message...)
	}
	return batch
}

This is the benchmark test, with each function above receiving ~64KB data.

func BenchmarkBuildMessageBatch(b *testing.B) {
	// Both implementations receive the same 1,000 existing 64-byte messages.
	message := bytes.Repeat([]byte{'x'}, 64)
	messages := make([][]byte, 1_000)
	for i := range messages {
		messages[i] = message
	}

	const outputBytes = 1_000 * 64

	b.Run("implementation=growing", func(b *testing.B) {
		var batch []byte
		b.ReportAllocs()
		b.SetBytes(outputBytes)
		for b.Loop() {
			batch = BuildMessageBatchGrowing(messages)
		}
		sinkMessageBatch = batch
	})

	b.Run("implementation=preallocated", func(b *testing.B) {
		var batch []byte
		b.ReportAllocs()
		b.SetBytes(outputBytes)
		for b.Loop() {
			batch = BuildMessageBatchPreallocated(messages)
		}
		sinkMessageBatch = batch
	})
}

With basic benchmarking comand below, we could say that has fewer allocation per operation (65536 B/op).

go test -run '^$' \
  -bench '^BenchmarkBuildMessageBatch$'
goos: linux
goarch: arm64
pkg: codec01
BenchmarkBuildMessageBatch/implementation=growing-12               18085             66364 ns/op         964.38 MB/s      285381 B/op         19 allocs/op
BenchmarkBuildMessageBatch/implementation=preallocated-12          75366             17774 ns/op        3600.68 MB/s       65536 B/op          1 allocs/op
PASS
ok      codec01 2.547s