From 363ae292bfdea54b73aa71ea22206f8953e47f21 Mon Sep 17 00:00:00 2001 From: zimbatm Date: Mon, 6 Apr 2026 18:55:27 +0200 Subject: [PATCH] splice: defer per-output spliceReal recursion behind genAttrs `//` forces its rhs to compute the merged keyset, so the original `// spliceReal (...)` recursed eagerly on every spliced derivation's outputs even when no specific output (.dev, .doc) was selected. genAttrs over the known output names with the splice in the value-thunk defers it: pkg.dev forces, pkg alone doesn't. Addresses #338231. Repro: EXPR='let pkgs = import ./. { localSystem = "x86_64-linux"; crossSystem = "aarch64-linux"; }; in (pkgs.python3.withPackages (ps: [ ps.requests ])).drvPath' NIX_SHOW_STATS=1 nix-instantiate --eval -E "$EXPR" drvPath byte-exact (mb82vdkqafg9i8x0makrgxw8xcc4y8lz both ways). Before: cpuTime: 0.649 nrFunctionCalls: 651343 nrOpUpdates: 153257 nrOpUpdateValuesCopied: 7908622 nrThunks: 2018744 values: 5061740 sets (bytes): 205342176 gc totalBytes: 320504688 After: cpuTime: 0.554 nrFunctionCalls: 586266 nrOpUpdates: 125579 nrOpUpdateValuesCopied: 5482176 nrThunks: 1494021 values: 3498806 sets (bytes): 141905680 gc totalBytes: 229067888 --- pkgs/top-level/splice.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/top-level/splice.nix b/pkgs/top-level/splice.nix index 718ed9f40f9d..e68815df0a51 100644 --- a/pkgs/top-level/splice.nix +++ b/pkgs/top-level/splice.nix @@ -52,12 +52,15 @@ let getOutputs (lib.optionalAttrs success value); getOutputs = value: lib.genAttrs (value.outputs or (lib.optional (value ? out) "out")) (output: value.${output}); + outputNames = defaultValue.outputs or (lib.optional (defaultValue ? out) "out"); + outputSplice = spliceReal ( + mapCrossIndex tryGetOutputs value' // { hostTarget = getOutputs value'.hostTarget; } + ); in # The derivation along with its outputs, which we recur # on to splice them together. if lib.isDerivation defaultValue then - augmentedValue - // spliceReal (mapCrossIndex tryGetOutputs value' // { hostTarget = getOutputs value'.hostTarget; }) + augmentedValue // lib.genAttrs outputNames (out: outputSplice.${out}) else if lib.isAttrs defaultValue then spliceReal value' else