about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authoradisbladis <adisbladis@gmail.com>2023-11-27 01:41:01 +1300
committeradisbladis <adisbladis@gmail.com>2023-11-27 11:37:56 +1300
commit7e07b3ecd55ac85675c26d9b09fab9996c410681 (patch)
tree294a4918d6a2b1f5742d94a6bcb9b1713bd8ca88 /lib
parent627af21e87ce5d6a456f485292ac4ac2bc1f469f (diff)
downloadnixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar.gz
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar.bz2
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar.lz
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar.xz
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.tar.zst
nixlib-7e07b3ecd55ac85675c26d9b09fab9996c410681.zip
lib.attrsets.hasAttrByPath: Don't allocate one extra list per lookup recursion
Using `tail` in a recursive loop like this needlessly allocates.
This changes the loop to look up by list index instead.
Diffstat (limited to 'lib')
-rw-r--r--lib/attrsets.nix16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index bf6c90bf1be6..107570627c66 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -58,13 +58,17 @@ rec {
     attrPath:
     # The nested attribute set to check
     e:
-    let attr = head attrPath;
+    let
+      lenAttrPath = length attrPath;
+      hasAttrByPath' = n: s: let
+        attr = elemAt attrPath n;
+      in (
+        if n == lenAttrPath then true
+        else if s ? ${attr} then hasAttrByPath' (n + 1) s.${attr}
+        else false
+      );
     in
-      if attrPath == [] then true
-      else if e ? ${attr}
-      then hasAttrByPath (tail attrPath) e.${attr}
-      else false;
-
+      hasAttrByPath' 0 e;
 
   /* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.