From b787ee3d40fba82228e5dc39c145bbb30af999fb Mon Sep 17 00:00:00 2001 From: Ben Siraphob Date: Tue, 14 Apr 2026 10:34:20 -0700 Subject: [PATCH] lib/modules: reduce allocations in evalModules and mergeModules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - When `evalModules` is called without deprecated `args`/`check` parameters (the common case), avoid `modules ++ []` which copies the entire module list for no reason. - `collectModules` was calling `collectStructuredModules` twice with identical arguments — once for `filterModules` and once for `toGraph`. Share the result via a `let` binding. - Replace `zipAttrsWith (n: v: v)` with `zipAttrs` - Replace `concatMap` with `filter`+`map` in `filterOverrides'` NixOS minimal eval improvement: -5.0% list_concats, -1.2% nrFunctionCalls, -0.7% nrThunks, -1.0% envs, -1.5% list_bytes. --- lib/modules.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/modules.nix b/lib/modules.nix index 419fc750e8d9..e369d98a6426 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -589,6 +589,8 @@ let in modulesPath: initialModules: args: { modules = filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args); + # Intentionally not shared with `modules` above: this allows `collected` + # to be garbage collected after `filterModules` returns. graph = toGraph modulesPath (collectStructuredModules unknownModule "" initialModules args); }; @@ -783,7 +785,7 @@ let prefix: modules: configs: let # an attrset 'name' => list of submodules that declare ‘name’. - declsByName = zipAttrsWith (n: v: v) ( + declsByName = zipAttrs ( map ( module: let @@ -838,7 +840,7 @@ let ) checkedConfigs ); # extract the definitions for each loc - rawDefinitionsByName = zipAttrsWith (n: v: v) ( + rawDefinitionsByName = zipAttrs ( map ( module: mapAttrs (n: value: { @@ -1439,7 +1441,7 @@ let def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def; in { - values = concatMap (def: if getPrio def == highestPrio then [ (strip def) ] else [ ]) defs; + values = map strip (filter (def: getPrio def == highestPrio) defs); inherit highestPrio; };