From 2d663b502da16d6dc480bff7f58297d176d04246 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 6 Aug 2011 19:45:43 +0000 Subject: * Cache the result of file evaluation (i.e, memoize evalFile()). This prevents files from being evaluated and stored as values multiple times. For instance, evaluation of the ‘system’ attribute in NixOS causes ‘nixpkgs/pkgs/lib/lists.nix’ to be evaluated 2019 times. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caching gives a modest speedup and a decent memory footprint reduction (e.g., from 1.44s to 1.28s, and from 81 MiB to 59 MiB with GC_INITIAL_HEAP_SIZE=100000 on my system). --- src/libexpr/eval.cc | 24 +++++++++++++----------- src/libexpr/eval.hh | 9 +++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5aee3f05eaa6..d0bdaf23822a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -431,17 +431,19 @@ Value * EvalState::maybeThunk(Env & env, Expr * expr) void EvalState::evalFile(const Path & path, Value & v) { - startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); - - Expr * e = parseExprFromFile(path); - - try { - /* !!! Maybe we should cache the evaluation result. */ - eval(e, v); - } catch (Error & e) { - addErrorPrefix(e, "while evaluating the file `%1%':\n", path); - throw; - } + FileEvalCache::iterator i = fileEvalCache.find(path); + if (i == fileEvalCache.end()) { + startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); + Expr * e = parseExprFromFile(path); + try { + eval(e, v); + } catch (Error & e) { + addErrorPrefix(e, "while evaluating the file `%1%':\n", path); + throw; + } + fileEvalCache[path] = v; + } else + v = i->second; } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 413234f2bf19..694d4407b847 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -211,8 +211,17 @@ private: bool allowUnsafeEquality; + /* A cache from path names to parse trees. */ std::map parseTrees; + /* A cache from path names to values. */ +#if HAVE_BOEHMGC + typedef std::map, gc_allocator > > FileEvalCache; +#else + typedef std::map FileEvalCache; +#endif + FileEvalCache fileEvalCache; + typedef list > SearchPath; SearchPath searchPath; SearchPath::iterator searchPathInsertionPoint; -- cgit 1.4.1