refactor(3p/nix): Use a static empty Bindings for 0-element attrs
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>
This commit is contained in:
parent
04ae293360
commit
5cd7cf93fc
1 changed files with 11 additions and 2 deletions
13
third_party/nix/src/libexpr/attr-set.cc
vendored
13
third_party/nix/src/libexpr/attr-set.cc
vendored
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
static Bindings ZERO_BINDINGS;
|
||||||
|
|
||||||
// This function inherits its name from previous implementations, in
|
// This function inherits its name from previous implementations, in
|
||||||
// which Bindings was backed by an array of elements which was scanned
|
// which Bindings was backed by an array of elements which was scanned
|
||||||
// linearly.
|
// linearly.
|
||||||
|
@ -21,6 +23,8 @@ namespace nix {
|
||||||
// This behaviour is mimicked by using .insert(), which will *not*
|
// This behaviour is mimicked by using .insert(), which will *not*
|
||||||
// override existing values.
|
// override existing values.
|
||||||
void Bindings::push_back(const Attr& attr) {
|
void Bindings::push_back(const Attr& attr) {
|
||||||
|
assert(this != &ZERO_BINDINGS);
|
||||||
|
|
||||||
auto [_, inserted] = attributes_.insert({attr.name, attr});
|
auto [_, inserted] = attributes_.insert({attr.name, attr});
|
||||||
|
|
||||||
if (!inserted) {
|
if (!inserted) {
|
||||||
|
@ -53,19 +57,24 @@ Bindings::iterator Bindings::begin() { return attributes_.begin(); }
|
||||||
Bindings::iterator Bindings::end() { return attributes_.end(); }
|
Bindings::iterator Bindings::end() { return attributes_.end(); }
|
||||||
|
|
||||||
void Bindings::merge(const Bindings& other) {
|
void Bindings::merge(const Bindings& other) {
|
||||||
|
assert(this != &ZERO_BINDINGS);
|
||||||
for (auto& [key, value] : other.attributes_) {
|
for (auto& [key, value] : other.attributes_) {
|
||||||
this->attributes_.insert_or_assign(key, value);
|
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;
|
return new (GC) Bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::mkAttrs(Value& v, size_t capacity) {
|
void EvalState::mkAttrs(Value& v, size_t capacity) {
|
||||||
clearValue(v);
|
clearValue(v);
|
||||||
v.type = tAttrs;
|
v.type = tAttrs;
|
||||||
v.attrs = Bindings::NewGC();
|
v.attrs = Bindings::NewGC(capacity);
|
||||||
nrAttrsets++;
|
nrAttrsets++;
|
||||||
nrAttrsInAttrsets += capacity;
|
nrAttrsInAttrsets += capacity;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue