mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
Merge pull request #13877 from xokdvium/opt-print-string
libstore: Get rid of allocations in printString, allocate 2K bytes on the stack
This commit is contained in:
commit
2746985d90
2 changed files with 56 additions and 22 deletions
|
|
@ -28,6 +28,27 @@ static void BM_ParseRealDerivationFile(benchmark::State & state, const std::stri
|
|||
state.SetBytesProcessed(state.iterations() * content.size());
|
||||
}
|
||||
|
||||
// Benchmark unparsing real derivation files
|
||||
static void BM_UnparseRealDerivationFile(benchmark::State & state, const std::string & filename)
|
||||
{
|
||||
// Read the file once
|
||||
std::ifstream file(filename);
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
std::string content = buffer.str();
|
||||
|
||||
auto store = openStore("dummy://");
|
||||
ExperimentalFeatureSettings xpSettings;
|
||||
auto drv = parseDerivation(*store, std::string(content), "test", xpSettings);
|
||||
|
||||
for (auto _ : state) {
|
||||
auto unparsed = drv.unparse(*store, /*maskOutputs=*/false);
|
||||
benchmark::DoNotOptimize(unparsed);
|
||||
assert(unparsed.size() == content.size());
|
||||
}
|
||||
state.SetBytesProcessed(state.iterations() * content.size());
|
||||
}
|
||||
|
||||
// Register benchmarks for actual test derivation files if they exist
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_ParseRealDerivationFile,
|
||||
|
|
@ -37,3 +58,11 @@ BENCHMARK_CAPTURE(
|
|||
BM_ParseRealDerivationFile,
|
||||
firefox,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv");
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_UnparseRealDerivationFile,
|
||||
hello,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv");
|
||||
BENCHMARK_CAPTURE(
|
||||
BM_UnparseRealDerivationFile,
|
||||
firefox,
|
||||
getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv");
|
||||
|
|
|
|||
|
|
@ -498,28 +498,33 @@ Derivation parseDerivation(
|
|||
*/
|
||||
static void printString(std::string & res, std::string_view s)
|
||||
{
|
||||
boost::container::small_vector<char, 64 * 1024> buffer;
|
||||
buffer.reserve(s.size() * 2 + 2);
|
||||
char * buf = buffer.data();
|
||||
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);
|
||||
res.reserve(res.size() + s.size() * 2 + 2);
|
||||
res += '"';
|
||||
static constexpr auto chunkSize = 1024;
|
||||
std::array<char, 2 * chunkSize + 2> buffer;
|
||||
while (!s.empty()) {
|
||||
auto chunk = s.substr(0, /*n=*/chunkSize);
|
||||
s.remove_prefix(chunk.size());
|
||||
char * buf = buffer.data();
|
||||
char * p = buf;
|
||||
for (auto c : chunk)
|
||||
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;
|
||||
res.append(buf, p - buf);
|
||||
}
|
||||
res += '"';
|
||||
}
|
||||
|
||||
static void printUnquotedString(std::string & res, std::string_view s)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue