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:
parent
9c2d63084b
commit
3e89ef597c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue