* The recent change in nixpkgs of calling `stdenv.mkDerivation'
instead of `derivation' triggered a huge slowdown in the Nix
  expression evaluator.  Total execution time of `nix-env -qa' went up
  by a factor of 60 or so.
  This scalability problem was caused by expressions such as
    (x: y: ... x ...) a b
  where `a' is a large term (say, the one in
  `all-packages-generic.nix').  Then the first beta-reduction would
  produce
    (y: ... a ...) b
  by substituting `a' for `x'.  The second beta-reduction would then
  substitute `b' for `y' into the body `... a ...', which is a large
  term due to `a', and thus causes a large traversal to be performed
  by substitute() in the second reduction.  This is however entirely
  redundant, since `a' cannot contain free variables (since we never
  substitute below a weak head normal form).
  The solution is to wrap substituted terms into a `Closed'
  constructor, i.e.,
    subst(subs, Var(x)) = Closed(e) iff subs[x] = e
  have substitution not descent into closed terms,
    subst(subs, Closed(x)) = Closed(x)
  and otherwise ignore them for evaluation,
    eval(Closed(x)) = eval(x).
* Fix a typo that caused incorrect substitutions to be performed in
  simple lambdas, e.g., `(x: x: x) a' would reduce to `(x: a)'.
			
			
This commit is contained in:
		
							parent
							
								
									df101d6fca
								
							
						
					
					
						commit
						c4ac2a164a
					
				
					 2 changed files with 11 additions and 2 deletions
				
			
		|  | @ -177,9 +177,13 @@ Expr substitute(const ATermMap & subs, Expr e) | |||
|     ATMatcher m; | ||||
|     ATerm name; | ||||
| 
 | ||||
|     /* As an optimisation, don't substitute in subterms known to be
 | ||||
|        closed. */ | ||||
|     if (atMatch(m, e) >> "Closed") return e; | ||||
| 
 | ||||
|     if (atMatch(m, e) >> "Var" >> name) { | ||||
|         Expr sub = subs.get(name); | ||||
|         return sub ? sub : e; | ||||
|         return sub ? ATmake("Closed(<term>)", sub) : e; | ||||
|     } | ||||
| 
 | ||||
|     /* In case of a function, filter out all variables bound by this
 | ||||
|  | @ -199,7 +203,7 @@ Expr substitute(const ATermMap & subs, Expr e) | |||
|             substitute(subs2, body)); | ||||
|     } | ||||
| 
 | ||||
|     if (atMatch(m, e) >> "Function" >> name >> body) { | ||||
|     if (atMatch(m, e) >> "Function1" >> name >> body) { | ||||
|         ATermMap subs2(subs); | ||||
|         subs2.remove(name); | ||||
|         return ATmake("Function1(<term>, <term>)", name, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue