diff options
author | Vincent Ambo <mail@tazj.in> | 2020-07-15T19·30+0100 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2020-07-16T00·37+0000 |
commit | 5cd7cf93fc6b6b58b05f579866a89bf22c6eacab (patch) | |
tree | 379288f99bd607276e4b5bfd4a607b982a0d61ac /third_party/nix/src/libexpr/attr-set.cc | |
parent | 04ae2933607eaed32c9d99eb3949953a88e63460 (diff) |
refactor(3p/nix): Use a static empty Bindings for 0-element attrs r/1305
A significant fraction of all created attribute sets are empty; hence this is an easy optimisation to make. Paired-With: Perry Lorier <isomer@tvl.fyi> Change-Id: I0884194d04c1ee95b2b239a253515f2152bc0856 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1179 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi>
Diffstat (limited to 'third_party/nix/src/libexpr/attr-set.cc')
-rw-r--r-- | third_party/nix/src/libexpr/attr-set.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/third_party/nix/src/libexpr/attr-set.cc b/third_party/nix/src/libexpr/attr-set.cc index c1b86387be8e..d44df990ad1e 100644 --- a/third_party/nix/src/libexpr/attr-set.cc +++ b/third_party/nix/src/libexpr/attr-set.cc @@ -10,6 +10,8 @@ namespace nix { +static Bindings ZERO_BINDINGS; + // This function inherits its name from previous implementations, in // which Bindings was backed by an array of elements which was scanned // linearly. @@ -21,6 +23,8 @@ namespace nix { // This behaviour is mimicked by using .insert(), which will *not* // override existing values. void Bindings::push_back(const Attr& attr) { + assert(this != &ZERO_BINDINGS); + auto [_, inserted] = attributes_.insert({attr.name, attr}); if (!inserted) { @@ -53,19 +57,24 @@ Bindings::iterator Bindings::begin() { return attributes_.begin(); } Bindings::iterator Bindings::end() { return attributes_.end(); } void Bindings::merge(const Bindings& other) { + assert(this != &ZERO_BINDINGS); for (auto& [key, value] : other.attributes_) { this->attributes_.insert_or_assign(key, value); } } -Bindings* Bindings::NewGC(size_t _capacity) { +Bindings* Bindings::NewGC(size_t capacity) { + if (capacity == 0) { + return &ZERO_BINDINGS; + } + return new (GC) Bindings; } void EvalState::mkAttrs(Value& v, size_t capacity) { clearValue(v); v.type = tAttrs; - v.attrs = Bindings::NewGC(); + v.attrs = Bindings::NewGC(capacity); nrAttrsets++; nrAttrsInAttrsets += capacity; } |