From 3e89ef597ce00dbf82a937aad9efab3c9c7b6dcf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Aug 2012 14:58:54 -0400 Subject: [PATCH] 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. --- src/libexpr/eval.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5351ca0c34..517a1151ec 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);