diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-02-21T12·01+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-02-21T12·01+0000 |
commit | 0a84137c4512e0a31802e94de7795e04f8ee2198 (patch) | |
tree | 8eca4837b1dc0fa0e8e9376fd3e8eb0a5268b759 | |
parent | 0ed89c569f95d884fb8107a555f8a03672a0fffd (diff) |
* checkVarDefs: don't check in closed terms, which don't have
undefined variables by definition. This matters for the implementation of "with", which does a call to checkVarDefs to see if the body of the with has no undefined variables. (It can't be checked at parse time because you don't know which variables are in the "with" attribute set.) If we check closed terms, then we check not just the with body but also the substituted terms, which are typically very large. This is the cause of the poor nix-env performance on Nixpkgs lately. It didn't happen earlier because "with" wasn't used very often in the past. This fix improves nix-env performance roughly 60x on current Nixpkgs. nix-env -qa is down from 29.3s to 0.5s on my laptop, and nix-env -qa --out-path is down from 229s to 3.39s. Not bad for a 1-line fix :-)
-rw-r--r-- | src/libexpr/nixexpr.cc | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 123513594512..1eeec2cf19f7 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -215,7 +215,11 @@ static void checkVarDefs2(set<Expr> & done, const ATermMap & defs, Expr e) ATerm with, body; ATermList rbnds, nrbnds; - if (matchVar(e, name)) { + /* Closed terms don't have free variables, so we don't have to + check by definition. */ + if (matchClosed(e, value)) return; + + else if (matchVar(e, name)) { if (!defs.get(name)) throw EvalError(format("undefined variable `%1%'") % aterm2String(name)); |