Look up the modules of a namespace by name instead of listing them all
Why
Every module of a package with a namespace opens the namespace's module, which maps each module of the package to its compiled name (module Price = Price-Shop). Opening a module builds its components, and building them walked every item of its signature, with a substitution entry, two table insertions and an environment binding per item, all kept for the rest of the compile. Each module of a namespaced package therefore did work proportional to the size of the package, and a clean build did quadratic work: on a package of about 4,900 modules, 46% of the build's CPU time went to building these components.
The components of a signature made only of aliases to persistent modules, such as a namespace's, are now looked up per name: Tbl.of_source makes a table whose entries are computed when a name is first looked up or visited, from an index of the signature's items. Folds and iterations visit the names in the order of the table the eager loop built, which decides, for example, the order of the candidates in a "did you mean" hint. The entries are the ones the eager loop made: an alias to a persistent module mentions no other item of its signature, so the substitution and the environment that the loop extended item by item can't change what it resolves to. Each entry still gets its own path and a substitution with its own item, so the declarations it returns are copies, shared as before in the .cmi and .cmt files. While the build system keeps decoded interfaces across the compiles of a build, each domain also keeps the indexes of the 16 most recently used such interfaces, by physical signature, until the build's files change.
Build modified (clean builds, default domains, medians of 15 interleaved pairs on a shared 8-core machine):
text
Every artifact of the 11 projects of a benchmark corpus (88,523 files, .cmt files included), of the runtime and of Belt is byte-identical to master's, with one domain and with the default number.
Review
- Do error messages and editor tools see the same modules in the same order? Lookups, folds and iterations over the table return what the eager table held, folds in the order of its keys. The new build test checks the "did you mean" hint, which lists the namespace's modules in that order, the type printed in an error, a module named like the namespace and a local module that hides one of the package.
- How long are the indexes kept? Only while the build file store is enabled, one per decoded interface: a domain keeps the 16 most recently used and drops them when the store's generation changes, as it drops its decoded interfaces.
bscand other compiles outside a build index the signature on each compile.