nix-config: cb1ec8d07250bfb0827677fb4c583421de43596a
1: From: Chris Warburton
2: Date: Fri, 27 Apr 2018 15:49:05 +0100
3: State: resolved
4: Subject: Speed up eval by reducing data dependencies
5: Message-Id: <96e3d8501ee406ef-0-artemis@nixos>
6: resolution: fixed
7:
8: Evaluating nix-config can take a while, which slows down many commands.
9: Since Nix is lazy, it should only evaluate what is needed, but running
10: commands verbosely shows lots of seemingly-random files being evaluated.
11:
12: This may be due to unnecessary data dependencies, for example we might
13: have an attrset like:
14:
15: {
16: a = import foo...;
17: b = bar...;
18: c = baz...;
19: }
20:
21: In this case, when we ask for (say) the 'b' parameter, the 'a' and 'c'
22: are ignored, 'foo' won't be imported and 'baz' won't be called. Only
23: 'bar' will be called.
24:
25: Now compare an alternative setup:
26:
27: fold (x: y: x // fiddleWith y)
28: {}
29: [ { name = "a"; value = import foo...; }
30: { name = "b"; value = bar...; }
31: { name = "c"; value = baz...; } ]
32:
33: The result is still an attrset, but it's been built up piecemeal from
34: each of these components. When we ask for 'b' in this case, the 'fold'
35: will be forced, to give the equivalent of:
36:
37: {} // fiddleWith { name = "a"; value = import foo..; }
38: // fiddleWith { name = "b"; value = bar...; }
39: // fiddleWith { name = "c"; value = baz...; }
40:
41: We can't get the 'b' attribute from this directly, since we don't know
42: which one of these parts defines it. We'll start from the last line
43: (since that would override anything defined before):
44:
45: {} // fiddleWith { name = "a"; value = import foo..; }
46: // fiddleWith { name = "b"; value = bar...; }
47: // { c = baz...; }
48:
49: This has forced the call to 'fiddleWith', which might cause quite a bit
50: of work, but *we* know (due to the way we just-so-happen to define
51: things) that there'll be no "b" in there. So we carry on:
52:
53: {} // fiddleWith { name = "a"; value = import foo..; }
54: // { b = bar...;
55: c = baz...; }
56:
57: Now we've called 'fiddleWith' again, for the 'b' case, which again might
58: do a bunch of work. This time there's a 'b' attribute defined, so we can
59: now pick that out and do the 'bar' call as in the above example.
60:
61: The question is, can we define things in a way which is more like the
62: first example, but still allow the names and attributes to be
63: calculated rather than hard-coded in an attrset literal?
Generated by git2html.