lib.meta: Avoid attrset allocation in platformMatch
Benchmarks (`nix-instantiate ./. -A python3`)
- Before
``` json
{
"cpuTime": 0.30625399947166443,
"envs": {
"bytes": 4484216,
"elements": 221443,
"number": 169542
},
"gc": {
"heapSize": 402915328,
"totalBytes": 53091024
},
"list": {
"bytes": 749424,
"concats": 4242,
"elements": 93678
},
"nrAvoided": 253991,
"nrFunctionCalls": 149848,
"nrLookups": 49614,
"nrOpUpdateValuesCopied": 1588326,
"nrOpUpdates": 10106,
"nrPrimOpCalls": 130356,
"nrThunks": 359013,
"sets": {
"bytes": 30432320,
"elements": 1860540,
"number": 41480
},
"sizes": {
"Attr": 16,
"Bindings": 16,
"Env": 16,
"Value": 24
},
"symbols": {
"bytes": 236218,
"number": 24459
},
"values": {
"bytes": 10504632,
"number": 437693
}
}
```
- After
```
{
"cpuTime": 0.29695799946784973,
"envs": {
"bytes": 3296712,
"elements": 169055,
"number": 121517
},
"gc": {
"heapSize": 402915328,
"totalBytes": 49044992
},
"list": {
"bytes": 504928,
"concats": 4242,
"elements": 63116
},
"nrAvoided": 175403,
"nrFunctionCalls": 110554,
"nrLookups": 44907,
"nrOpUpdateValuesCopied": 1588326,
"nrOpUpdates": 10106,
"nrPrimOpCalls": 82330,
"nrThunks": 306625,
"sets": {
"bytes": 29943328,
"elements": 1843076,
"number": 28382
},
"sizes": {
"Attr": 16,
"Bindings": 16,
"Env": 16,
"Value": 24
},
"symbols": {
"bytes": 236218,
"number": 24459
},
"values": {
"bytes": 9037752
,
"number": 376573
}
}
```
This commit is contained in:
parent
2819a35bf4
commit
4b4d413817
2 changed files with 42 additions and 10 deletions
32
lib/meta.nix
32
lib/meta.nix
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) matchAttrs any all;
|
||||||
|
inherit (builtins) isString;
|
||||||
|
|
||||||
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,14 +88,21 @@ rec {
|
||||||
We can inject these into a pattern for the whole of a structured platform,
|
We can inject these into a pattern for the whole of a structured platform,
|
||||||
and then match that.
|
and then match that.
|
||||||
*/
|
*/
|
||||||
platformMatch = platform: elem: let
|
platformMatch = platform: elem: (
|
||||||
pattern =
|
# Check with simple string comparison if elem was a string.
|
||||||
if builtins.isString elem
|
#
|
||||||
then { system = elem; }
|
# The majority of comparisons done with this function will be against meta.platforms
|
||||||
else if elem?parsed
|
# which contains a simple platform string.
|
||||||
then elem
|
#
|
||||||
else { parsed = elem; };
|
# Avoiding an attrset allocation results in significant performance gains (~2-30) across the board in OfBorg
|
||||||
in lib.matchAttrs pattern platform;
|
# because this is a hot path for nixpkgs.
|
||||||
|
if isString elem then platform ? system && elem == platform.system
|
||||||
|
else matchAttrs (
|
||||||
|
# Normalize platform attrset.
|
||||||
|
if elem ? parsed then elem
|
||||||
|
else { parsed = elem; }
|
||||||
|
) platform
|
||||||
|
);
|
||||||
|
|
||||||
/* Check if a package is available on a given platform.
|
/* Check if a package is available on a given platform.
|
||||||
|
|
||||||
|
@ -102,8 +114,8 @@ rec {
|
||||||
2. None of `meta.badPlatforms` pattern matches the given platform.
|
2. None of `meta.badPlatforms` pattern matches the given platform.
|
||||||
*/
|
*/
|
||||||
availableOn = platform: pkg:
|
availableOn = platform: pkg:
|
||||||
((!pkg?meta.platforms) || lib.any (platformMatch platform) pkg.meta.platforms) &&
|
((!pkg?meta.platforms) || any (platformMatch platform) pkg.meta.platforms) &&
|
||||||
lib.all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []);
|
all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []);
|
||||||
|
|
||||||
/* Get the corresponding attribute in lib.licenses
|
/* Get the corresponding attribute in lib.licenses
|
||||||
from the SPDX ID.
|
from the SPDX ID.
|
||||||
|
|
|
@ -1948,4 +1948,24 @@ runTests {
|
||||||
testGetExe'FailureSecondArg = testingThrow (
|
testGetExe'FailureSecondArg = testingThrow (
|
||||||
getExe' { type = "derivation"; } "dir/executable"
|
getExe' { type = "derivation"; } "dir/executable"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
testPlatformMatch = {
|
||||||
|
expr = meta.platformMatch { system = "x86_64-linux"; } "x86_64-linux";
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
testPlatformMatchAttrs = {
|
||||||
|
expr = meta.platformMatch (systems.elaborate "x86_64-linux") (systems.elaborate "x86_64-linux").parsed;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
testPlatformMatchNoMatch = {
|
||||||
|
expr = meta.platformMatch { system = "x86_64-darwin"; } "x86_64-linux";
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
testPlatformMatchMissingSystem = {
|
||||||
|
expr = meta.platformMatch { } "x86_64-linux";
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue