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 <cstring>
#include <memory>
#include <new>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
@ -1130,7 +1132,11 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
path. */
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
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();
constexpr size_t chunkSize = 65536;
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;
Finally cleanup([&]() {
dump.resize(oldSize + got);
dump = {dumpBuffer.get(), dump.size() + got};
});
try {
got = source.read(dump.data() + oldSize, want);
got = source.read(dumpBuffer.get() + oldSize, want);
} catch (EndOfFile &) {
inMemory = true;
break;
@ -1171,7 +1182,8 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
else
writeFile(tempPath, bothSource);
dump.clear();
dumpBuffer.reset();
dump = {};
}
auto [hash, size] = hashSink->finish();