Skip to content

Instantly share code, notes, and snippets.

@KEINOS
Created May 1, 2023 07:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KEINOS/20ac97cfb6f94311b4b15f52528d298c to your computer and use it in GitHub Desktop.
Save KEINOS/20ac97cfb6f94311b4b15f52528d298c to your computer and use it in GitHub Desktop.
[Golang] Converting uint64 to byte slices.

Converting uint64 to []byte in Go

tl; dr

Using LittleEndian.PutUint64 function from encoding/binary package is much faster than bit shifting.

0.3468n/op vs 3.905n/op

import "encoding/binary"

// Uint64ToBytes converts the given uint64 value to slice of bytes.
func Uint64ToBytes(val uint64) []byte {
	b := make([]byte, 8)
	binary.LittleEndian.PutUint64(b, val)

	return b
}

ts; dr

Functions

// Ordinary way using bit shifting
func convA(val uint64) []byte {
	r := make([]byte, 8)
	for i := uint64(0); i < 8; i++ {
		r[i] = byte((val >> (i * 8)) & 0xff)
	}

	return r
}

// Use `encoding/binary` package
func convB(val uint64) []byte {
	b := make([]byte, 8)
	binary.LittleEndian.PutUint64(b, val)

	return b
}

Testing

func Test_is_equal(t *testing.T) {
	val := uint64(1234567890)

	byteValA := convA(val)
	byteValB := convB(val)

	require.Equal(t, byteValA, byteValB)
}

Benchmarking

func Benchmark_conv(b *testing.B) {
	const val = uint64(1234567890)

	b.Run("convA", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			_ = convA(val)
		}
	})

	b.Run("convB", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			_ = convB(val)
		}
	})
}

Bench results

$ go test -run=^$ -benchmem -bench ^Benchmark_conv$ -count 10 ./... > bench.txt

$ benchstat bench.txt
goos: darwin
goarch: amd64
pkg: example/uint64tobytes
cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
              │  bench.txt   │
              │    sec/op    │
_conv/convA-4    3.905n ± 6%
_conv/convB-4   0.3468n ± 1%
geomean          1.164n

              │  bench.txt   │
              │     B/op     │
_conv/convA-4   0.000 ± 0%
_conv/convB-4   0.000 ± 0%
geomean                    ¹
¹ summaries must be >0 to compute geomean

              │  bench.txt   │
              │  allocs/op   │
_conv/convA-4   0.000 ± 0%
_conv/convB-4   0.000 ± 0%
geomean                    ¹
¹ summaries must be >0 to compute geomean
  • Env info:
    • macOS Monterey (12.6.5, darwin/amd64)
    • Go v1.20.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment