Optimise Derivation::unparse()
In nix-instantiate --dry-run '<nixpkgs/nixos/release-combined.nix>' -A nixos.tests.simple.x86_64-linux this reduces time spent in unparse() from 9.15% to 4.31%. The main culprit was appending characters one at a time to the destination string. Even though the string has enough capacity, push_back() still needs to check this on every call.
This commit is contained in:
parent
401b5bc541
commit
75db069f92
|
@ -213,15 +213,26 @@ Derivation Store::derivationFromPath(const StorePath & drvPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void printString(string & res, const string & s)
|
static void printString(string & res, std::string_view s)
|
||||||
|
{
|
||||||
|
char buf[s.size() * 2 + 2];
|
||||||
|
char * p = buf;
|
||||||
|
*p++ = '"';
|
||||||
|
for (auto c : s)
|
||||||
|
if (c == '\"' || c == '\\') { *p++ = '\\'; *p++ = c; }
|
||||||
|
else if (c == '\n') { *p++ = '\\'; *p++ = 'n'; }
|
||||||
|
else if (c == '\r') { *p++ = '\\'; *p++ = 'r'; }
|
||||||
|
else if (c == '\t') { *p++ = '\\'; *p++ = 't'; }
|
||||||
|
else *p++ = c;
|
||||||
|
*p++ = '"';
|
||||||
|
res.append(buf, p - buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void printUnquotedString(string & res, std::string_view s)
|
||||||
{
|
{
|
||||||
res += '"';
|
res += '"';
|
||||||
for (const char * i = s.c_str(); *i; i++)
|
res.append(s);
|
||||||
if (*i == '\"' || *i == '\\') { res += "\\"; res += *i; }
|
|
||||||
else if (*i == '\n') res += "\\n";
|
|
||||||
else if (*i == '\r') res += "\\r";
|
|
||||||
else if (*i == '\t') res += "\\t";
|
|
||||||
else res += *i;
|
|
||||||
res += '"';
|
res += '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +250,19 @@ static void printStrings(string & res, ForwardIterator i, ForwardIterator j)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class ForwardIterator>
|
||||||
|
static void printUnquotedStrings(string & res, ForwardIterator i, ForwardIterator j)
|
||||||
|
{
|
||||||
|
res += '[';
|
||||||
|
bool first = true;
|
||||||
|
for ( ; i != j; ++i) {
|
||||||
|
if (first) first = false; else res += ',';
|
||||||
|
printUnquotedString(res, *i);
|
||||||
|
}
|
||||||
|
res += ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string Derivation::unparse(const Store & store, bool maskOutputs,
|
string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
std::map<std::string, StringSet> * actualInputs) const
|
std::map<std::string, StringSet> * actualInputs) const
|
||||||
{
|
{
|
||||||
|
@ -249,10 +273,10 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto & i : outputs) {
|
for (auto & i : outputs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, i.first);
|
s += '('; printUnquotedString(s, i.first);
|
||||||
s += ','; printString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
|
s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
|
||||||
s += ','; printString(s, i.second.hashAlgo);
|
s += ','; printUnquotedString(s, i.second.hashAlgo);
|
||||||
s += ','; printString(s, i.second.hash);
|
s += ','; printUnquotedString(s, i.second.hash);
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,24 +285,24 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
if (actualInputs) {
|
if (actualInputs) {
|
||||||
for (auto & i : *actualInputs) {
|
for (auto & i : *actualInputs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, i.first);
|
s += '('; printUnquotedString(s, i.first);
|
||||||
s += ','; printStrings(s, i.second.begin(), i.second.end());
|
s += ','; printUnquotedStrings(s, i.second.begin(), i.second.end());
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto & i : inputDrvs) {
|
for (auto & i : inputDrvs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, store.printStorePath(i.first));
|
s += '('; printUnquotedString(s, store.printStorePath(i.first));
|
||||||
s += ','; printStrings(s, i.second.begin(), i.second.end());
|
s += ','; printUnquotedStrings(s, i.second.begin(), i.second.end());
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s += "],";
|
s += "],";
|
||||||
auto paths = store.printStorePathSet(inputSrcs); // FIXME: slow
|
auto paths = store.printStorePathSet(inputSrcs); // FIXME: slow
|
||||||
printStrings(s, paths.begin(), paths.end());
|
printUnquotedStrings(s, paths.begin(), paths.end());
|
||||||
|
|
||||||
s += ','; printString(s, platform);
|
s += ','; printUnquotedString(s, platform);
|
||||||
s += ','; printString(s, builder);
|
s += ','; printString(s, builder);
|
||||||
s += ','; printStrings(s, args.begin(), args.end());
|
s += ','; printStrings(s, args.begin(), args.end());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue