diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-08-13T18·58-0400 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-08-13T18·58-0400 |
commit | 3e89ef597ce00dbf82a937aad9efab3c9c7b6dcf (patch) | |
tree | 60d4896f8c8b063ce7d2354fb357da9a2a13c0ba /src/libexpr | |
parent | 9c2d63084bd4f6a04210cd52b4fce054d248bc6b (diff) |
Optimise concatenating a list to an empty list
More precisely, in concatLists, if all lists except one are empty, then just return the non-empty list. This reduces the number of list element allocations by 32% when evaluating a NixOS system configuration.
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5351ca0c345a..517a1151ec69 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -922,11 +922,19 @@ void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v) void EvalState::concatLists(Value & v, unsigned int nrLists, Value * * lists) { nrListConcats++; - + + Value * nonEmpty = 0; unsigned int len = 0; for (unsigned int n = 0; n < nrLists; ++n) { forceList(*lists[n]); - len += lists[n]->list.length; + unsigned int l = lists[n]->list.length; + len += l; + if (l) nonEmpty = lists[n]; + } + + if (nonEmpty && len == nonEmpty->list.length) { + v = *nonEmpty; + return; } mkList(v, len); |