libexpr: specialize builtins.elem scans over attribute set needles#16019
libexpr: specialize builtins.elem scans over attribute set needles#16019bouk wants to merge 1 commit into
Conversation
When the needle is an attribute set (the common case of testing whether a derivation or attrset is in a list), hoist the needle-side work that eqValues would otherwise redo for every element—the derivation check and the attribute-set size—and reject non-matching elements without the generic comparison machinery. Assisted-by: Claude Fable 5
xokdvium
left a comment
There was a problem hiding this comment.
-
would be nice to understand what's causing so many derivation equality checks and what the responsible code pattern is.
-
Maybe eqValues should be reworked in such a way that it can work with a pre-forced value if that's actually the problem here.
| if (elem->attrs() == needleAttrs) { | ||
| res = true; | ||
| break; | ||
| } |
There was a problem hiding this comment.
Hm, what's this pointer equality doing here? I'd be incredibly vary of introducing even more dubious pointer equality short-circuits, since it might change the semantics in a very annoying/hard to understand way.
|
I seem to recall that nixpkgs had some idiotic usage of |
|
We do have a bunch of Python packages on our system, I'll try to figure it out this week |
|
I think @llakala reminded me of that issue and they were fixing it in nixpkgs? |
|
I tried to do that last week, but was getting a change in hash for python for an unclear reason. This diff was resulting in markupsafe being removed as a dependency of python itself (transitive through mako). Still not sure why. requiredPythonModules =
- drvs:
let
- modules = lib.filter hasPythonModule drvs;
+ withKey = pkg: {
+ key = pkg.outPath;
+ value = pkg;
+ };
+ collect = e: if e ? requiredPythonModules then map withKey e.requiredPythonModules else [ ];
in
- lib.unique (
- [ python ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules)
+ drvs:
+ lib.map (e: e.value) (
+ builtins.genericClosure {
+ startSet = map withKey ([ python ] ++ lib.filter hasPythonModule drvs);
+ operator = collect;
+ }
); |
Motivation
I ran Claude Fable 5 (earlier this week before it got pulled) with the prompt 'make this nix eval 2x as fast' and let it run overnight to see what it came up with. This was one of the highest-impact changes, with a -5% improvement in runtime for a medium-complex NixOS configuration.
Context
I've human-reviewed the change and it makes sense to me, but I'm not knowledgeable enough about the nix codebase to say if there's a better way to structure this.
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.