Compare performance of listToAttrs
, foldl'
, getAttr
, and attrs.${name}
.
Conclusion:
Use of foldl'
for cases where listToAttrs
could be used instead has a major
performance difference.
When processing the same attrset, foldl'
was roughly 120 times slower!
let
attrs = builtins.readDir /nix/store;
rsl = builtins.foldl' ( acc: name: acc // { ${name} = attrs.${name}; } ) {}
( builtins.attrNames attrs );
in builtins.deepSeq rsl null
$ NIX_SHOW_STATS=1 nix eval -f ex1.nix;
{
"cpuTime": 6.032771110534668,
"envs": {
"bytes": 1516736,
"elements": 63198,
"number": 63197
},
"gc": {
"heapSize": 8137211904,
"totalBytes": 7998121264
},
"list": {
"bytes": 252816,
"concats": 0,
"elements": 31602
},
"nrAvoided": 4,
"nrFunctionCalls": 63196,
"nrLookups": 31602,
"nrOpUpdateValuesCopied": 499232600,
"nrOpUpdates": 31598,
"nrPrimOpCalls": 4,
"nrThunks": 31603,
"sets": {
"bytes": 7989746128,
"elements": 499295932,
"number": 63201
},
"sizes": {
"Attr": 16,
"Bindings": 16,
"Env": 16,
"Value": 24
},
"symbols": {
"bytes": 1738428,
"number": 31845
},
"values": {
"bytes": 3036504,
"number": 126521
}
}
let
attrs = builtins.readDir /nix/store;
proc = name: { inherit name; value = builtins.getAttr name attrs; };
rsl = builtins.listToAttrs ( map proc ( builtins.attrNames attrs ) );
in builtins.deepSeq rsl null
$ NIX_SHOW_STATS=1 nix eval -f ex2.nix;
{
"cpuTime": 0.048695001751184464,
"envs": {
"bytes": 758392,
"elements": 31601,
"number": 31599
},
"gc": {
"heapSize": 402915328,
"totalBytes": 10122112
},
"list": {
"bytes": 505600,
"concats": 0,
"elements": 63200
},
"nrAvoided": 94799,
"nrFunctionCalls": 31598,
"nrLookups": 31602,
"nrOpUpdateValuesCopied": 0,
"nrOpUpdates": 0,
"nrPrimOpCalls": 31603,
"nrThunks": 31603,
"sets": {
"bytes": 2530128,
"elements": 126528,
"number": 31605
},
"sizes": {
"Attr": 16,
"Bindings": 16,
"Env": 16,
"Value": 24
},
"symbols": {
"bytes": 1738429,
"number": 31845
},
"values": {
"bytes": 3036528,
"number": 126522
}
}
let
attrs = builtins.readDir /nix/store;
proc = name: { inherit name; value = attrs.${name}; };
rsl = builtins.listToAttrs ( map proc ( builtins.attrNames attrs ) );
in builtins.deepSeq rsl null
$ NIX_SHOW_STATS=1 nix eval -f ex3.nix;
{
"cpuTime": 0.042525000870227814,
"envs": {
"bytes": 758392,
"elements": 31601,
"number": 31599
},
"gc": {
"heapSize": 402915328,
"totalBytes": 10122112
},
"list": {
"bytes": 505600,
"concats": 0,
"elements": 63200
},
"nrAvoided": 31603,
"nrFunctionCalls": 31598,
"nrLookups": 31602,
"nrOpUpdateValuesCopied": 0,
"nrOpUpdates": 0,
"nrPrimOpCalls": 5,
"nrThunks": 31603,
"sets": {
"bytes": 2530128,
"elements": 126528,
"number": 31605
},
"sizes": {
"Attr": 16,
"Bindings": 16,
"Env": 16,
"Value": 24
},
"symbols": {
"bytes": 1738429,
"number": 31845
},
"values": {
"bytes": 3036528,
"number": 126522
}
}