Skip to content

Commit b9f2dac

Browse files
authored
Preallocate entries slice in DeserializeEntries (#285)
DeserializeEntries reads the entry count from the directory stream and then builds the result with make([]EntryV3, 0) plus append. Because the slice starts at zero capacity, append reallocates and copies the backing array as it grows - 27 times for a full-planet leaf directory (~62k entries) - and each discarded intermediate array is transient garbage. The exact entry count is already known before the append loops, so size the slice capacity to it up front. The decode logic is otherwise unchanged and the returned entries are identical. Decoding a 62,746-entry leaf (gzip), allocations measured with -benchmem: before: 8,849,368 B/op 216 allocs/op after: 1,579,005 B/op 190 allocs/op (-82% bytes, -26 allocs)
1 parent 8a474e3 commit b9f2dac

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

pmtiles/directory.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ func SerializeEntries(entries []EntryV3, compression Compression) []byte {
323323
}
324324

325325
func DeserializeEntries(data *bytes.Buffer, compression Compression) []EntryV3 {
326-
entries := make([]EntryV3, 0)
327-
328326
var reader io.Reader
329327

330328
if compression == NoCompression {
@@ -338,6 +336,10 @@ func DeserializeEntries(data *bytes.Buffer, compression Compression) []EntryV3 {
338336

339337
numEntries, _ := binary.ReadUvarint(byteReader)
340338

339+
// Preallocate the entries slice to the known count so the append loops below
340+
// do not repeatedly reallocate and copy the backing array as it grows.
341+
entries := make([]EntryV3, 0, numEntries)
342+
341343
lastID := uint64(0)
342344
for i := uint64(0); i < numEntries; i++ {
343345
tmp, _ := binary.ReadUvarint(byteReader)

0 commit comments

Comments
 (0)