From 5cd7cf93fc6b6b58b05f579866a89bf22c6eacab Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 15 Jul 2020 20:30:13 +0100 Subject: 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 Change-Id: I0884194d04c1ee95b2b239a253515f2152bc0856 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1179 Tested-by: BuildkiteCI Reviewed-by: glittershark --- third_party/nix/src/libexpr/attr-set.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'third_party') diff --git a/third_party/nix/src/libexpr/attr-set.cc b/third_party/nix/src/libexpr/attr-set.cc index c1b86387be..d44df990ad 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; } -- cgit 1.4.1