authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-02 12:00:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-02 12:00:43-07:00
log90ac62cc751fa85bf572e281f65064bf2935ff9c
tree6bf43fb5ac293fd3728cd9a34c78c8fe5c51bfca
parent00b0beb682881da083b548423019483924736c1e

std.compress.lzma2: optimize appendLz

make the hot loop be a for loop without any failures or allocation. change a O(N) addition into O(1)

1 files changed, 11 insertions(+), 16 deletions(-)

lib/std/compress/lzma2.zig+11-16
...@@ -79,23 +79,18 @@ pub const AccumBuffer = struct {...@@ -79,23 +79,18 @@ pub const AccumBuffer = struct {
79 _ = writer;79 _ = writer;
8080
81 const buf_len = self.buf.items.len;81 const buf_len = self.buf.items.len;
82 if (dist > buf_len) {82 if (dist > buf_len) return error.CorruptInput;
83 return error.CorruptInput;
84 }
8583
86 // ensure we have enough capacity for all new bytes.84 try self.buf.ensureUnusedCapacity(allocator, len);
87 // This prevents the buffer's memory from being reallocated (and freed)85 const buffer = self.buf.allocatedSlice();
88 // while we are still reading from it.86 const src = buffer[buf_len - dist ..][0..len];
89 try self.buf.ensureTotalCapacity(allocator, buf_len + len);87 const dst = buffer[buf_len..][0..len];
9088
91 var offset = buf_len - dist;89 // This is not a @memmove; it intentionally repeats patterns caused by
92 var i: usize = 0;90 // iterating one byte at a time.
93 while (i < len) : (i += 1) {91 for (dst, src) |*d, s| d.* = s;
94 const x = self.buf.items[offset];92
95 // Since capacity is guaranteed, it's safe to use appendAssumeCapacity.93 self.buf.items.len = buf_len + len;
96 self.buf.appendAssumeCapacity(x);
97 offset += 1;
98 }
99 self.len += len;94 self.len += len;
100 }95 }
10196