mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-13 01:08:41 -09:00
Improve JSON import performance by another 10%
Profiling showed that string parsing was a bottleneck. We rarely need the full power of JSON strings, though, so we can optimize for the common case of plain strings without escape codes. Keeping the slower string parser as fallback, of course.
This commit is contained in:
parent
d2e8dd8a90
commit
1e56c8604e
1 changed files with 40 additions and 22 deletions
|
|
@ -82,11 +82,12 @@ const Parser = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a string (after the ") into buf.
|
fn stringContentSlow(p: *Parser, buf: []u8, head: u8, off: usize) []u8 {
|
||||||
// Any characters beyond the size of the buffer are consumed but otherwise discarded.
|
@setCold(true);
|
||||||
fn stringContent(p: *Parser, buf: []u8) []u8 {
|
var b = head;
|
||||||
var n: usize = 0;
|
var n = off;
|
||||||
while (true) switch (p.nextByte()) {
|
while (true) {
|
||||||
|
switch (b) {
|
||||||
'"' => break,
|
'"' => break,
|
||||||
'\\' => switch (p.nextByte()) {
|
'\\' => switch (p.nextByte()) {
|
||||||
'"' => if (n < buf.len) { buf[n] = '"'; n += 1; },
|
'"' => if (n < buf.len) { buf[n] = '"'; n += 1; },
|
||||||
|
|
@ -104,12 +105,29 @@ const Parser = struct {
|
||||||
},
|
},
|
||||||
else => p.die("invalid escape sequence"),
|
else => p.die("invalid escape sequence"),
|
||||||
},
|
},
|
||||||
0x20, 0x21, 0x23...0x5b, 0x5d...0xff => |b| if (n < buf.len) { buf[n] = b; n += 1; },
|
0x20, 0x21, 0x23...0x5b, 0x5d...0xff => if (n < buf.len) { buf[n] = b; n += 1; },
|
||||||
else => p.die("invalid character in string"),
|
else => p.die("invalid character in string"),
|
||||||
};
|
}
|
||||||
|
b = p.nextByte();
|
||||||
|
}
|
||||||
return buf[0..n];
|
return buf[0..n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read a string (after the ") into buf.
|
||||||
|
// Any characters beyond the size of the buffer are consumed but otherwise discarded.
|
||||||
|
fn stringContent(p: *Parser, buf: []u8) []u8 {
|
||||||
|
// The common case (for ncdu dumps): string fits in the given buffer and does not contain any escapes.
|
||||||
|
var n: usize = 0;
|
||||||
|
var b = p.nextByte();
|
||||||
|
while (n < buf.len and b >= 0x20 and b != '"' and b != '\\') {
|
||||||
|
buf[n] = b;
|
||||||
|
n += 1;
|
||||||
|
b = p.nextByte();
|
||||||
|
}
|
||||||
|
if (b == '"') return buf[0..n];
|
||||||
|
return p.stringContentSlow(buf, b, n);
|
||||||
|
}
|
||||||
|
|
||||||
fn string(p: *Parser, buf: []u8) []u8 {
|
fn string(p: *Parser, buf: []u8) []u8 {
|
||||||
if (p.nextChr() != '"') p.die("expected string");
|
if (p.nextChr() != '"') p.die("expected string");
|
||||||
return p.stringContent(buf);
|
return p.stringContent(buf);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue