* 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. 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).
This commit is contained in:
parent
510033e783
commit
2d663b502d
2 changed files with 22 additions and 11 deletions
|
@ -431,17 +431,19 @@ Value * EvalState::maybeThunk(Env & env, Expr * expr)
|
||||||
|
|
||||||
void EvalState::evalFile(const Path & path, Value & v)
|
void EvalState::evalFile(const Path & path, Value & v)
|
||||||
{
|
{
|
||||||
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
FileEvalCache::iterator i = fileEvalCache.find(path);
|
||||||
|
if (i == fileEvalCache.end()) {
|
||||||
Expr * e = parseExprFromFile(path);
|
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
||||||
|
Expr * e = parseExprFromFile(path);
|
||||||
try {
|
try {
|
||||||
/* !!! Maybe we should cache the evaluation result. */
|
eval(e, v);
|
||||||
eval(e, v);
|
} catch (Error & e) {
|
||||||
} catch (Error & e) {
|
addErrorPrefix(e, "while evaluating the file `%1%':\n", path);
|
||||||
addErrorPrefix(e, "while evaluating the file `%1%':\n", path);
|
throw;
|
||||||
throw;
|
}
|
||||||
}
|
fileEvalCache[path] = v;
|
||||||
|
} else
|
||||||
|
v = i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -211,8 +211,17 @@ private:
|
||||||
|
|
||||||
bool allowUnsafeEquality;
|
bool allowUnsafeEquality;
|
||||||
|
|
||||||
|
/* A cache from path names to parse trees. */
|
||||||
std::map<Path, Expr *> parseTrees;
|
std::map<Path, Expr *> parseTrees;
|
||||||
|
|
||||||
|
/* A cache from path names to values. */
|
||||||
|
#if HAVE_BOEHMGC
|
||||||
|
typedef std::map<Path, Value, std::less<Path>, gc_allocator<std::pair<const Path, Value> > > FileEvalCache;
|
||||||
|
#else
|
||||||
|
typedef std::map<Path, Value> FileEvalCache;
|
||||||
|
#endif
|
||||||
|
FileEvalCache fileEvalCache;
|
||||||
|
|
||||||
typedef list<std::pair<string, Path> > SearchPath;
|
typedef list<std::pair<string, Path> > SearchPath;
|
||||||
SearchPath searchPath;
|
SearchPath searchPath;
|
||||||
SearchPath::iterator searchPathInsertionPoint;
|
SearchPath::iterator searchPathInsertionPoint;
|
||||||
|
|
Loading…
Reference in a new issue