aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorIgor Anić <igor.anic@gmail.com>2024-03-13 18:22:08 +0100
committerIgor Anić <igor.anic@gmail.com>2024-03-13 18:22:08 +0100
commita21f9b6d8b9b027e64795dcdec40494bad76675e (patch)
tree7e4e28e59005ba7b09e4e9ba5a3935f1e1a1dc70 /lib/std
parentb9cca3b63dbcedadbda1c884e5b3333c8458b30d (diff)
downloadzig-a21f9b6d8b9b027e64795dcdec40494bad76675e.tar.gz
zig-a21f9b6d8b9b027e64795dcdec40494bad76675e.zip
compress.xz: remove copyForwards from tight loop
In the example from the issue #19052 to_read holds 213_315_584 uncompressed bytes. Calling read with small output results in many shifts of that big buffer. This removes need to shift to_read after each read.
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/compress/xz/block.zig15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/std/compress/xz/block.zig b/lib/std/compress/xz/block.zig
index cd2c465dc5..6e0a09c8dd 100644
--- a/lib/std/compress/xz/block.zig
+++ b/lib/std/compress/xz/block.zig
@@ -34,6 +34,7 @@ pub fn Decoder(comptime ReaderType: type) type {
check: xz.Check,
err: ?Error,
to_read: ArrayListUnmanaged(u8),
+ read_pos: usize,
block_count: usize,
fn init(allocator: Allocator, in_reader: ReaderType, check: xz.Check) !Self {
@@ -43,6 +44,7 @@ pub fn Decoder(comptime ReaderType: type) type {
.check = check,
.err = null,
.to_read = .{},
+ .read_pos = 0,
.block_count = 0,
};
}
@@ -57,13 +59,12 @@ pub fn Decoder(comptime ReaderType: type) type {
pub fn read(self: *Self, output: []u8) Error!usize {
while (true) {
- if (self.to_read.items.len > 0) {
- const input = self.to_read.items;
+ const input = self.to_read.items[self.read_pos..];
+ if (input.len > 0) {
const n = @min(input.len, output.len);
@memcpy(output[0..n], input[0..n]);
- std.mem.copyForwards(u8, input, input[n..]);
- self.to_read.shrinkRetainingCapacity(input.len - n);
- if (self.to_read.items.len == 0 and self.err != null) {
+ self.read_pos += n;
+ if (self.read_pos == self.to_read.items.len and self.err != null) {
if (self.err.? == DecodeError.EndOfStreamWithNoError) {
return n;
}
@@ -77,6 +78,10 @@ pub fn Decoder(comptime ReaderType: type) type {
}
return self.err.?;
}
+ if (self.read_pos > 0) {
+ self.to_read.shrinkRetainingCapacity(0);
+ self.read_pos = 0;
+ }
self.readBlock() catch |e| {
self.err = e;
};