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 {...@@ -34,6 +34,7 @@ pub fn Decoder(comptime ReaderType: type) type {
34 check: xz.Check,34 check: xz.Check,
35 err: ?Error,35 err: ?Error,
36 to_read: ArrayListUnmanaged(u8),36 to_read: ArrayListUnmanaged(u8),
37 read_pos: usize,
37 block_count: usize,38 block_count: usize,
3839
39 fn init(allocator: Allocator, in_reader: ReaderType, check: xz.Check) !Self {40 fn init(allocator: Allocator, in_reader: ReaderType, check: xz.Check) !Self {
...@@ -43,6 +44,7 @@ pub fn Decoder(comptime ReaderType: type) type {...@@ -43,6 +44,7 @@ pub fn Decoder(comptime ReaderType: type) type {
43 .check = check,44 .check = check,
44 .err = null,45 .err = null,
45 .to_read = .{},46 .to_read = .{},
47 .read_pos = 0,
46 .block_count = 0,48 .block_count = 0,
47 };49 };
48 }50 }
...@@ -57,13 +59,12 @@ pub fn Decoder(comptime ReaderType: type) type {...@@ -57,13 +59,12 @@ pub fn Decoder(comptime ReaderType: type) type {
5759
58 pub fn read(self: *Self, output: []u8) Error!usize {60 pub fn read(self: *Self, output: []u8) Error!usize {
59 while (true) {61 while (true) {
60 if (self.to_read.items.len > 0) {62 const input = self.to_read.items[self.read_pos..];
61 const input = self.to_read.items;63 if (input.len > 0) {
62 const n = @min(input.len, output.len);64 const n = @min(input.len, output.len);
63 @memcpy(output[0..n], input[0..n]);65 @memcpy(output[0..n], input[0..n]);
64 std.mem.copyForwards(u8, input, input[n..]);66 self.read_pos += n;
65 self.to_read.shrinkRetainingCapacity(input.len - n);67 if (self.read_pos == self.to_read.items.len and self.err != null) {
66 if (self.to_read.items.len == 0 and self.err != null) {
67 if (self.err.? == DecodeError.EndOfStreamWithNoError) {68 if (self.err.? == DecodeError.EndOfStreamWithNoError) {
68 return n;69 return n;
69 }70 }
...@@ -77,6 +78,10 @@ pub fn Decoder(comptime ReaderType: type) type {...@@ -77,6 +78,10 @@ pub fn Decoder(comptime ReaderType: type) type {
77 }78 }
78 return self.err.?;79 return self.err.?;
79 }80 }
81 if (self.read_pos > 0) {
82 self.to_read.shrinkRetainingCapacity(0);
83 self.read_pos = 0;
84 }
80 self.readBlock() catch |e| {85 self.readBlock() catch |e| {
81 self.err = e;86 self.err = e;
82 };87 };