From eff165425a1a225ac22427ec94b25da9ef6d6e04 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 15 Jul 2020 23:51:25 +0100 Subject: refactor(3p/libstore): Optimise nix::printString Slight performance optimisation of nix::printString by copying chunks of the input string which do not need escaping as contiguous blocks. Paired-With: Perry Lorier Change-Id: I48bad90c8f2831ae4524c814a12b1982989922f9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1184 Tested-by: BuildkiteCI Reviewed-by: edef Reviewed-by: glittershark --- third_party/nix/src/libstore/derivations.cc | 49 ++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/third_party/nix/src/libstore/derivations.cc b/third_party/nix/src/libstore/derivations.cc index 64d1c6a15144..59b2a505a307 100644 --- a/third_party/nix/src/libstore/derivations.cc +++ b/third_party/nix/src/libstore/derivations.cc @@ -199,22 +199,47 @@ Derivation Store::derivationFromPath(const Path& drvPath) { } } +const char* findChunk(const char* begin) { + while (*begin != 0 && *begin != '\"' && *begin != '\\' && *begin != '\n' && + *begin != '\r' && *begin != '\t') { + begin++; + } + + return begin; +} + static void printString(std::string& res, const std::string& s) { res += '"'; - for (const char* i = s.c_str(); *i != 0; i++) { - 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; + + const char* it = s.c_str(); + while (*it != 0) { + const char* end = findChunk(it); + std::copy(it, end, std::back_inserter(res)); + + it = end; + + switch (*it) { + case '"': + case '\\': + res += "\\"; + res += *it; + break; + case '\n': + res += "\\n"; + break; + case '\r': + res += "\\r"; + break; + case '\t': + res += "\\t"; + break; + default: + continue; } + + it++; } + res += '"'; } -- cgit 1.4.1