Skip to content

Commit

Permalink
Use zero-copy decoding for reflists
Browse files Browse the repository at this point in the history
Reflists are basically stored as arrays of strings, which are quite
space-efficient in MessagePack. Thus, using zero-copy decoding results
in nice performance and memory savings, because the overhead of separate
allocations ends up far exceeding the overhead of the original slice.

With the included benchmark run for 20s with -benchmem, the runtime,
memory usage, and allocations go from ~740us/op, ~192KiB/op, and 4100
allocs/op to ~240us/op, ~97KiB/op, and 13 allocs/op, respectively.

Signed-off-by: Ryan Gonzalez <[email protected]>
  • Loading branch information
refi64 authored and neolynx committed Apr 21, 2024
1 parent 0db3014 commit 0f8cdaa
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
4 changes: 3 additions & 1 deletion deb/reflist.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ func (l *PackageRefList) Encode() []byte {

// Decode decodes msgpack representation into PackageRefLit
func (l *PackageRefList) Decode(input []byte) error {
decoder := codec.NewDecoderBytes(input, &codec.MsgpackHandle{})
handle := &codec.MsgpackHandle{}
handle.ZeroCopy = true
decoder := codec.NewDecoderBytes(input, handle)
return decoder.Decode(l)
}

Expand Down
17 changes: 17 additions & 0 deletions deb/reflist_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,20 @@ func BenchmarkReflistSimpleMerge(b *testing.B) {
l.Merge(r, false, true)
}
}

func BenchmarkReflistDecode(b *testing.B) {
const count = 4096

r := NewPackageRefList()
for i := 0; i < count; i++ {
r.Refs = append(r.Refs, []byte(fmt.Sprintf("Pamd64 pkg%d %d", i, i)))
}

sort.Sort(r)
data := r.Encode()

b.ResetTimer()
for i := 0; i < b.N; i++ {
(&PackageRefList{}).Decode(data)
}
}

0 comments on commit 0f8cdaa

Please sign in to comment.