Merge pull request from yorickvP/fast-repl-load

Fix accidental O(n^2 * log n) performance in NixRepl::addAttrsToScope
This commit is contained in:
Eelco Dolstra 2021-12-27 16:56:25 +01:00 committed by GitHub
commit 0e90b13ab1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 2 deletions
src

View file

@ -368,6 +368,13 @@ struct StaticEnv
[](const Vars::value_type & a, const Vars::value_type & b) { return a.first < b.first; }); [](const Vars::value_type & a, const Vars::value_type & b) { return a.first < b.first; });
} }
void deduplicate()
{
const auto last = std::unique(vars.begin(), vars.end(),
[] (const Vars::value_type & a, const Vars::value_type & b) { return a.first == b.first; });
vars.erase(last, vars.end());
}
Vars::const_iterator find(const Symbol & name) const Vars::const_iterator find(const Symbol & name) const
{ {
Vars::value_type key(name, 0); Vars::value_type key(name, 0);

View file

@ -661,8 +661,16 @@ void NixRepl::reloadFiles()
void NixRepl::addAttrsToScope(Value & attrs) void NixRepl::addAttrsToScope(Value & attrs)
{ {
state->forceAttrs(attrs); state->forceAttrs(attrs);
for (auto & i : *attrs.attrs) if (displ + attrs.attrs->size() >= envSize)
addVarToScope(i.name, *i.value); throw Error("environment full; cannot add more variables");
for (auto & i : *attrs.attrs) {
staticEnv.vars.emplace_back(i.name, displ);
env->values[displ++] = i.value;
varNames.insert((string) i.name);
}
staticEnv.sort();
staticEnv.deduplicate();
notice("Added %1% variables.", attrs.attrs->size()); notice("Added %1% variables.", attrs.attrs->size());
} }