3
0
Fork 0
forked from mirrors/nixpkgs

lib/modules: optimize byName

the foldl is equivalent to a zip with concat. list concatenation in nix
is an O(n) operation, which makes this operation extremely inefficient
when large numbers of modules are involved.

this change reduces the number of list elements by 7 million on the
system used to write this, total memory spent on lists by 58MB, and
total memory allocated on the GC heap by almost 100MB (with a similar
reduction in GC heap size). it's also slightly faster.
This commit is contained in:
pennae 2021-12-24 22:36:08 +01:00
parent b3c4e64b31
commit afecbb2f75

View file

@ -37,6 +37,7 @@ let
toList
types
warnIf
zipAttrsWith
;
inherit (lib.options)
isOption
@ -442,7 +443,8 @@ rec {
}
*/
byName = attr: f: modules:
foldl' (acc: module:
zipAttrsWith (n: concatLists)
(map (module:
if !(builtins.isAttrs module.${attr}) then
throw ''
You're trying to declare a value of type `${builtins.typeOf module.${attr}}'
@ -454,11 +456,8 @@ rec {
this option by e.g. referring to `man 5 configuration.nix'!
''
else
acc // (mapAttrs (n: v:
(acc.${n} or []) ++ f module v
) module.${attr}
)
) {} modules;
mapAttrs (n: f module) module.${attr}
) modules);
# an attrset 'name' => list of submodules that declare name.
declsByName = byName "options" (module: option:
[{ inherit (module) _file; options = option; }]