aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-13 14:58:54 -0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-13 14:58:54 -0400
commit3e89ef597ce00dbf82a937aad9efab3c9c7b6dcf (patch)
tree60d4896f8c8b063ce7d2354fb357da9a2a13c0ba /src
parent9c2d63084bd4f6a04210cd52b4fce054d248bc6b (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')
-rw-r--r--src/libexpr/eval.cc12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 5351ca0c3..517a1151e 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);