about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-03-09T15·09+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-03-09T15·09+0000
commit922697c8b27570b6c76a472266507b73f6b79f7f (patch)
treef9e189f6bbc77d036f4ee6c091561710d85cc389
parent6dca5c9099b92b6a93071197aa606a31ccd83a37 (diff)
* Big speedup (factor > 2.5) in all nix-env operations that do actual
  instantiation, e.g. "nix-env -i" and "nix-env -qas" (but not
  "nix-env -qa").  It turns out that many redundant calls to
  addToStore(path) were made, which reads and hashes the entire path.
  For instance, the bash bootstrap binary in Nixpkgs would be read and
  hashed many times.  As a result nix-env would spend around 92% of
  its time in the function sha256_block (according to callgrind).
  Some simple memoization fixes this.

-rw-r--r--src/libexpr/eval.hh5
-rw-r--r--src/libexpr/primops.cc12
2 files changed, 14 insertions, 3 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 11185159c123..602f63fdedaf 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -11,6 +11,10 @@
 typedef map<Path, PathSet> DrvRoots;
 typedef map<Path, Hash> DrvHashes;
 
+/* Cache for calls to addToStore(); maps source paths to the store
+   paths. */
+typedef map<Path, Path> SrcToStore;
+
 struct EvalState;
 
 /* Note: using a ATermVector is safe here, since when we call a primop
@@ -24,6 +28,7 @@ struct EvalState
     ATermMap primOps;
     DrvRoots drvRoots;
     DrvHashes drvHashes; /* normalised derivation hashes */
+    SrcToStore srcToStore; 
     Expr blackHole;
 
     unsigned int nrEvaluated;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 31fff0b493e8..77721a5a8d87 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -165,9 +165,15 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
             if (isDerivation(srcPath))
                 throw Error(format("file names are not allowed to end in `%1%'")
                     % drvExtension);
-            Path dstPath(addToStore(srcPath));
-            printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
-                % srcPath % dstPath);
+            Path dstPath;
+            if (state.srcToStore[srcPath] != "")
+                dstPath = state.srcToStore[srcPath];
+            else {
+                dstPath = addToStore(srcPath);
+                state.srcToStore[srcPath] = dstPath;
+                printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
+                    % srcPath % dstPath);
+            }
             drv.inputSrcs.insert(dstPath);
             ss.push_back(dstPath);
         }