authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-03-13 18:22:08+01:00
committergravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2024-03-13 18:22:08+01:00
loga21f9b6d8b9b027e64795dcdec40494bad76675e
tree7e4e28e59005ba7b09e4e9ba5a3935f1e1a1dc70
parentb9cca3b63dbcedadbda1c884e5b3333c8458b30d

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.

1 files changed, 10 insertions(+), 5 deletions(-)

lib/std/compress/xz/block.zig+10-5
......@@ -34,6 +34,7 @@ pub fn Decoder(comptime ReaderType: type) type {
3434 check: xz.Check,
3535 err: ?Error,
3636 to_read: ArrayListUnmanaged(u8),
37 read_pos: usize,
3738 block_count: usize,
3839
3940 fn init(allocator: Allocator, in_reader: ReaderType, check: xz.Check) !Self {
......@@ -43,6 +44,7 @@ pub fn Decoder(comptime ReaderType: type) type {
4344 .check = check,
4445 .err = null,
4546 .to_read = .{},
47 .read_pos = 0,
4648 .block_count = 0,
4749 };
4850 }
......@@ -57,13 +59,12 @@ pub fn Decoder(comptime ReaderType: type) type {
5759
5860 pub fn read(self: *Self, output: []u8) Error!usize {
5961 while (true) {
60 if (self.to_read.items.len > 0) {
61 const input = self.to_read.items;
62 const input = self.to_read.items[self.read_pos..];
63 if (input.len > 0) {
6264 const n = @min(input.len, output.len);
6365 @memcpy(output[0..n], input[0..n]);
64 std.mem.copyForwards(u8, input, input[n..]);
65 self.to_read.shrinkRetainingCapacity(input.len - n);
66 if (self.to_read.items.len == 0 and self.err != null) {
66 self.read_pos += n;
67 if (self.read_pos == self.to_read.items.len and self.err != null) {
6768 if (self.err.? == DecodeError.EndOfStreamWithNoError) {
6869 return n;
6970 }
......@@ -77,6 +78,10 @@ pub fn Decoder(comptime ReaderType: type) type {
7778 }
7879 return self.err.?;
7980 }
81 if (self.read_pos > 0) {
82 self.to_read.shrinkRetainingCapacity(0);
83 self.read_pos = 0;
84 }
8085 self.readBlock() catch |e| {
8186 self.err = e;
8287 };