stdenv: Move all stdenv lookups out of mkDerivation#431756
stdenv: Move all stdenv lookups out of mkDerivation#431756philiptaron merged 1 commit intoNixOS:masterfrom
Conversation
|
I still have this on my list to review, but I won't be able to be at a computer until a little later this week. These sorts of PRs need careful attention…Although I have a strong belief that you have not introduced any regressions with this change. |
philiptaron
left a comment
There was a problem hiding this comment.
Requesting changes only for the defaultConfigurePlatformsFlags searching and the system hoisting. Everything else is me puzzling over how this whole thing came to be.
There was a problem hiding this comment.
This isn't true anymore, based on the usage of ++ below. That would cause an eval failure.
There was a problem hiding this comment.
Yeah, I don't know where it came from. Maybe this was the case in the days of yore.
There was a problem hiding this comment.
I'd prefer to remove it in this PR, since we're mutating configureFlags so much. I leave that preference in your hands.
There was a problem hiding this comment.
Ah, sorry, I wasn't fast enough here. I guess, such trivial change can be done any time later :)
There was a problem hiding this comment.
We can avoid this list concatenation in the common case by testing the following booleans.
attrs ? configureFlags: the derivation specifiedconfigureFlagsattrs ? configurePlatforms: the derivation specifiedconfigurePlatforms
The common case is !attrs ? configureFlags and !attrs ? configurePlatforms, which ought to just be defaultConfigurePlatformsFlags.
Here's the truth table that I'm thinking of.
attrs ? configureFlags |
attrs ? configurePlatforms |
Meaning | Result |
|---|---|---|---|
false |
false |
Defaults in every case | defaultConfigurePlatformsFlags |
false |
true |
Non-default platforms, need to test for target | Do elem "target" logic on the platforms |
true |
false |
Some flags are set, default platforms (other common case) | configureFlags ++ defaultConfigurePlatformsFlags |
true |
true |
Rare case | configureFlags plus the elem target logic. |
What do you think?
There was a problem hiding this comment.
Do
elem "target"logic on the platforms
Note that we'll need to do this logic for all variants, not just for "target".
I also wonder if this elem logic could be replaced with one concatMap instead. It might change the order of arguments in some cases not present in Nixpkgs.
Overall I'd prefer to do this optimisation separately to see its effect in isolation.
There was a problem hiding this comment.
In this case, because the logic is so mutated in this PR, and there was this line in the headmatter:
For some reason lists concats go 14% up, but defaultConfigurePlatformsFlags optimisation removes ~7% of them.
I suspect all of these list concats are here, in this logic, and most could be removed through judicious refactors of logic.
That's why I was nudging for something like this truth table be extracted into a set of Nix expressions and used in this PR, to make it be even more a Pareto improvement.
There was a problem hiding this comment.
I suspect all of these list concats are here, in this logic, and most could be removed through judicious refactors of logic.
But I strictly reduced the overall number of concats here: it was 3 for all derivations, and even before defaultConfigurePlatformsFlags it remained 3, with this optimisation, it's only 3 for ~100 or so packages that set configurePlatforms. All this means that I missed some list concats somewhere, but not here...
All lookups and expressions that don't depend on derivation attrs are moved to the outer let block. Saves over 10% lookups for eval on x86_64-linux, along with 53MiB memory (over 1%). For some reason lists concats go 14% up, but defaultConfigurePlatformsFlags optimisation removes ~7% of them. Overall time is down ~3%.
a29daaa to
7151ae1
Compare
philiptaron
left a comment
There was a problem hiding this comment.
I still want the system thing changed the way I outline in this review, but I won't block the PR on that preference.
Strongly suspect that the change to use if ... then ... else ... instead of optional* will be net positive in this file.
There was a problem hiding this comment.
I'd prefer to remove it in this PR, since we're mutating configureFlags so much. I leave that preference in your hands.
There was a problem hiding this comment.
In this case, because the logic is so mutated in this PR, and there was this line in the headmatter:
For some reason lists concats go 14% up, but defaultConfigurePlatformsFlags optimisation removes ~7% of them.
I suspect all of these list concats are here, in this logic, and most could be removed through judicious refactors of logic.
That's why I was nudging for something like this truth table be extracted into a set of Nix expressions and used in this PR, to make it be even more a Pareto improvement.
| stdenvHasCC = stdenv.hasCC; | ||
| stdenvShell = stdenv.shell; | ||
|
|
||
| buildPlatformSystem = buildPlatform.system; |
There was a problem hiding this comment.
| buildPlatformSystem = buildPlatform.system; |
| # attribute of `buildPlatform` matches Nix's degree of specificity. | ||
| # exactly. | ||
| inherit (stdenv.buildPlatform) system; | ||
| system = buildPlatformSystem; |
There was a problem hiding this comment.
| system = buildPlatformSystem; | |
| inherit (buildPlatform) system; |
My mental model of how Nix holds references says that this inherit both matches the comment and is at least as good as the extraction into the let block, possibly better.
There was a problem hiding this comment.
Huh, it would be interesting to see the effect of such change. I thought that inherit (x) y; is strictly equivalent to y = x.y, and Nix doesn't try to optimise x.y at all.
There was a problem hiding this comment.
In fact, here: https://github.com/NixOS/nix/blob/218cd6c16c0981cc32a45e3a15be1d3c1a68eb85/src/libexpr/parser.y#L419-L422 the parser essentially replaces inherit (x) y; with x = x.y; and then in https://github.com/NixOS/nix/blob/218cd6c16c0981cc32a45e3a15be1d3c1a68eb85/src/libexpr/eval.cc#L1237-L1242 we allocate additional env (I don't quite understand, why) if there is any inherit (x) y attrs and then we do necessary binding at eval time. It means that my removing all "inherit from" attrs from this attrset we save one env allocation per call.
YorikSar
left a comment
There was a problem hiding this comment.
@philiptaron I'm sorry for taking too long to respond and thanks a lot for a quick merge. I hope I'll be able to find some time for deeper optimisations in this area in the future, this was fun.
There was a problem hiding this comment.
I suspect all of these list concats are here, in this logic, and most could be removed through judicious refactors of logic.
But I strictly reduced the overall number of concats here: it was 3 for all derivations, and even before defaultConfigurePlatformsFlags it remained 3, with this optimisation, it's only 3 for ~100 or so packages that set configurePlatforms. All this means that I missed some list concats somewhere, but not here...
There was a problem hiding this comment.
Ah, sorry, I wasn't fast enough here. I guess, such trivial change can be done any time later :)
| # attribute of `buildPlatform` matches Nix's degree of specificity. | ||
| # exactly. | ||
| inherit (stdenv.buildPlatform) system; | ||
| system = buildPlatformSystem; |
There was a problem hiding this comment.
Huh, it would be interesting to see the effect of such change. I thought that inherit (x) y; is strictly equivalent to y = x.y, and Nix doesn't try to optimise x.y at all.
|
@YorikSar are you at NixCon 2025? |
|
@philiptaron no, I’m not. I’ll also be barely available in the coming month. |
All lookups and expressions that don't depend on derivation attrs are moved to the outer let block. Saves over 10% lookups for eval on x86_64-linux, along with 53MiB memory (over 1%).
For some reason lists concats go 14% up, but defaultConfigurePlatformsFlags optimisation removes ~7% of them.
Overall time is down ~3%.
Things done
Add a 👍 reaction to pull requests you find important.