memset less in addToStoreFromDump

resizing a std::string clears the newly added bytes, which is not
necessary here and comes with a ~1.4% slowdown on our test nixos config.

〉 nix eval --raw --impure --expr 'with import <nixpkgs/nixos> {}; system'

before:

  Time (mean ± σ):      4.486 s ±  0.003 s    [User: 3.978 s, System: 0.507 s]
  Range (min … max):    4.482 s …  4.492 s    10 runs

after:

  Time (mean ± σ):      4.429 s ±  0.002 s    [User: 3.929 s, System: 0.500 s]
  Range (min … max):    4.427 s …  4.433 s    10 runs
This commit is contained in:
pennae 2023-12-10 04:15:51 +01:00
parent 3c200da242
commit 0218e4e6c3

View file

@ -18,6 +18,8 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <memory>
#include <new>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/select.h> #include <sys/select.h>
@ -1130,7 +1132,11 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
path. */ path. */
bool inMemory = false; bool inMemory = false;
std::string dump; struct Free {
void operator()(void* v) { free(v); }
};
std::unique_ptr<char, Free> dumpBuffer(nullptr);
std::string_view dump;
/* Fill out buffer, and decide whether we are working strictly in /* Fill out buffer, and decide whether we are working strictly in
memory based on whether we break out because the buffer is full memory based on whether we break out because the buffer is full
@ -1139,13 +1145,18 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
auto oldSize = dump.size(); auto oldSize = dump.size();
constexpr size_t chunkSize = 65536; constexpr size_t chunkSize = 65536;
auto want = std::min(chunkSize, settings.narBufferSize - oldSize); auto want = std::min(chunkSize, settings.narBufferSize - oldSize);
dump.resize(oldSize + want); if (auto tmp = realloc(dumpBuffer.get(), oldSize + want)) {
dumpBuffer.release();
dumpBuffer.reset((char*) tmp);
} else {
throw std::bad_alloc();
}
auto got = 0; auto got = 0;
Finally cleanup([&]() { Finally cleanup([&]() {
dump.resize(oldSize + got); dump = {dumpBuffer.get(), dump.size() + got};
}); });
try { try {
got = source.read(dump.data() + oldSize, want); got = source.read(dumpBuffer.get() + oldSize, want);
} catch (EndOfFile &) { } catch (EndOfFile &) {
inMemory = true; inMemory = true;
break; break;
@ -1171,7 +1182,8 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
else else
writeFile(tempPath, bothSource); writeFile(tempPath, bothSource);
dump.clear(); dumpBuffer.reset();
dump = {};
} }
auto [hash, size] = hashSink->finish(); auto [hash, size] = hashSink->finish();