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.
This commit is contained in:
Eelco Dolstra 2012-08-13 14:58:54 -04:00
parent 9c2d63084b
commit 3e89ef597c

View file

@ -922,11 +922,19 @@ void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
void EvalState::concatLists(Value & v, unsigned int nrLists, Value * * lists) void EvalState::concatLists(Value & v, unsigned int nrLists, Value * * lists)
{ {
nrListConcats++; nrListConcats++;
Value * nonEmpty = 0;
unsigned int len = 0; unsigned int len = 0;
for (unsigned int n = 0; n < nrLists; ++n) { for (unsigned int n = 0; n < nrLists; ++n) {
forceList(*lists[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); mkList(v, len);