From 922697c8b27570b6c76a472266507b73f6b79f7f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 9 Mar 2006 15:09:18 +0000 Subject: [PATCH] * 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. --- src/libexpr/eval.hh | 5 +++++ src/libexpr/primops.cc | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 11185159c..602f63fde 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -11,6 +11,10 @@ typedef map DrvRoots; typedef map DrvHashes; +/* Cache for calls to addToStore(); maps source paths to the store + paths. */ +typedef map 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 31fff0b49..77721a5a8 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); }