Commit 878a3872 authored by zimbatm's avatar zimbatm
Browse files

lib.systems.equals: optimize removeFunctions

Replace filterAttrs + lib.isFunction with removeAttrs + builtins.filter
+ builtins.isFunction. System attrs are never __functor-style attrsets,
so lib.isFunction's wrapper is unnecessary overhead. The double negation
(!pred ∘ !isFunction) also cancels out.

NIX_SHOW_STATS delta on hello.drvPath:

  nrFunctionCalls:  229,883 -> 154,411   (-32.8%)
  envs.number:      250,215 -> 174,743   (-30.2%)
  envs.bytes:         4.6M -> 3.4M       (-26.4%)
  nrAvoided:        291,314 -> 216,054   (-25.8%)
  gc.totalBytes:     49.7M -> 48.5M      (-2.4%)

Repro:

  NIX_SHOW_STATS=1 nix-instantiate --eval \
    -E '(import ./. {}).hello.drvPath' 2>stats.json >/dev/null
  jq . stats.json
parent d8c4c60d
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -43,7 +43,9 @@ let
  */
  equals =
    let
      removeFunctions = a: filterAttrs (_: v: !isFunction v) a;
      # perf: avoid lib.isFunction because system attrs are never __functor-style attrsets.
      removeFunctions =
        a: removeAttrs a (builtins.filter (n: builtins.isFunction a.${n}) (builtins.attrNames a));
    in
    a: b: removeFunctions a == removeFunctions b;