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.