Increase io.BufferedInStream readByte speed by ~75%

master
frmdstryr 2019-12-04 13:23:18 -05:00 committed by Andrew Kelley
parent 8829b5316b
commit 1baaf9a503
2 changed files with 16 additions and 1 deletions

View File

@ -107,6 +107,13 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
fn readFn(in_stream: *Stream, dest: []u8) !usize {
const self = @fieldParentPtr(Self, "stream", in_stream);
// Hot path for one byte reads
if (dest.len == 1 and self.end_index > self.start_index) {
dest[0] = self.buffer[self.start_index];
self.start_index += 1;
return 1;
}
var dest_index: usize = 0;
while (true) {
const dest_space = dest.len - dest_index;
@ -126,6 +133,13 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
if (dest_space < buffer_size) {
self.start_index = 0;
self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]);
// Shortcut
if (self.end_index >= dest_space) {
mem.copy(u8, dest[dest_index..], self.buffer[0..dest_space]);
self.start_index = dest_space;
return dest.len;
}
} else {
// asking for so much data that buffering is actually less efficient.
// forward the request directly to the unbuffered stream

View File

@ -174,7 +174,8 @@ pub fn InStream(comptime ReadError: type) type {
/// Reads 1 byte from the stream or returns `error.EndOfStream`.
pub fn readByte(self: *Self) !u8 {
var result: [1]u8 = undefined;
try self.readNoEof(result[0..]);
const amt_read = try self.read(result[0..]);
if (amt_read < 1) return error.EndOfStream;
return result[0];
}