What takes evaluation time?

i am told that having more modules takes more evaluation time, but is it just having the modules themselves imported?
if that is the case, what would be the harm in exposing all options to all modules in one module and only importing modules if their enable option is true?

From what I remember from sources I cannot remember right now, yes.

That you then could no longer set the other options.

IIIRC the fix was, to not gate use so many config = lib.mkIf cfg.enabled or only include the required modules.

more modules takes more evaluation time, but is it just having the modules themselves imported?

Yes, just importing a module will cause it to be evaluated. This is the reason why NixOS is becoming slower over time: the number of module is growing and since in principle a module can interact with any other one, the only way is to evaluate them all.

At some point we may have to select some “essential” set of modules to be imported unconditionally and make the users manually import what they need.

what would be the harm in exposing all options to all modules in one module and only importing modules if their enable option is true?

If I understood, you’re describing something like this:

{ config, ... }:
{
  options = {
    module-a.enable = ...;
    module-b.enable = ...;
    module-c.enable = ...;
  };

  imports = [ ]
    ++ lib.optional config.module-a.enable ./module-a.nix
    ++ lib.optional config.module-b.enable ./module-b.nix
    ++ lib.optional config.module-c.enable ./module-c.nix
    ++ ...;
}

This should cause an infinite recursion IIRC.

i haven’t tested it myself, but a redditor had success with this method:

config = mkIf cfg.minimal ({
    services.getty.autologinUser = "root";
} // import (modulesPath + "/profiles/minimal.nix") { inherit config lib; });

they didn’t report infinite recursion, so what would be the drawback of using this?

Ah, that’s what you mean by importing.
Yes, that works if you’re only sticking to configuring existing options: so no options or imports section, but only config. For a full NixOS module (all three sections) you have to let the module system do the merging.

Anyway, I don’t think you should worry about performance if you’re just splitting your configuration into a dozen files or so.

understood. for a little more specificity, do you know what parts of module evaluation take time? for example, if i had more options, would it take longer to evaluate? is the main contributor simply it having to evaluate another module? anything like that

I’d say that merely setting some options will not increase the eval time significantly: most of the time is due to the large number of modules in Nixpkgs.

Unless, of course, you’re doing the infamous IFD somewhere in your configuration, setting the value of an option to a huge generated expression, importing a huge generated file, or something like that.

1 Like

This would still import minimal.nix in order to push the mkIf to the option definition, as part of the merging logic of modules, and would only add the extra condition to every option defined inside minimal.nix, thus adding extra work to delay one extra property.

While this is not supposed to be an optimization, this is something I have considered, to add the ability to add logic to the imports, for granting option definitions or filtering them. I just need to set some time up to do it …