summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorpennae <github@quasiparticle.net>2021-12-24 22:36:08 +0100
committerpennae <github@quasiparticle.net>2021-12-25 00:19:44 +0100
commitafecbb2f7534a0530fc0da53af74d0bb85697d36 (patch)
treed4630bd58e384297ed065e51a1ffa5ef5023d02a /lib
parentb3c4e64b31b2e5cc1f28eae9098bbc5fec0f4069 (diff)
downloadnixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar.gz
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar.bz2
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar.lz
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar.xz
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.tar.zst
nixpkgs-afecbb2f7534a0530fc0da53af74d0bb85697d36.zip
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/modules.nix11
1 files changed, 5 insertions, 6 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index 573bf40e4b3..091c72e30aa 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -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; }]