use translation table for drv string parsing

the table is very small compared to cache sizes and a single indexed
load is faster than three comparisons.

before:

Benchmark 1: nix eval --raw --impure --expr 'with import <nixpkgs/nixos> {}; system'
  Time (mean ± σ):      6.907 s ±  0.012 s    [User: 5.272 s, System: 1.429 s]
  Range (min … max):    6.893 s …  6.926 s    10 runs

after:

Benchmark 1: nix eval --raw --impure --expr 'with import <nixpkgs/nixos> {}; system'
  Time (mean ± σ):      6.883 s ±  0.016 s    [User: 5.250 s, System: 1.424 s]
  Range (min … max):    6.860 s …  6.905 s    10 runs
This commit is contained in:
pennae 2023-12-26 05:44:52 +01:00
parent 79d3d412ca
commit 02c64abf1e

View file

@ -174,6 +174,17 @@ struct StringViewStream {
return c; return c;
} }
}; };
constexpr struct Escapes {
char map[256];
constexpr Escapes() {
for (int i = 0; i < 256; i++) map[i] = (char) (unsigned char) i;
map[(int) (unsigned char) 'n'] = '\n';
map[(int) (unsigned char) 'r'] = '\r';
map[(int) (unsigned char) 't'] = '\t';
}
char operator[](char c) const { return map[(unsigned char) c]; }
} escapes;
} }
@ -213,10 +224,7 @@ static BackedStringView parseString(StringViewStream & str)
for (c = content.begin(), end = content.end(); c != end; c++) for (c = content.begin(), end = content.end(); c != end; c++)
if (*c == '\\') { if (*c == '\\') {
c++; c++;
if (*c == 'n') res += '\n'; res += escapes[*c];
else if (*c == 'r') res += '\r';
else if (*c == 't') res += '\t';
else res += *c;
} }
else res += *c; else res += *c;
return res; return res;