The compilation model of OCaml modules

Has there been any write-up on the way OCaml achieves fast compilation times
(similar to this by Rob Pike on Go’s compilation model)?

It would be interesting to compare the approaches of two of the fastest compilers out there.

6 Likes

As far as I can tell, very few of the design choices described (re. compilation model / build times) in the document you link are specific to Go, they are common to most language implementations that support so-called “separate compilation”.

There are important design differences that impact build times and depend on the language:

  • Certain language features, providing various forms of inlining, generate a lot of code and can dramatically increase build times. This is the case with C++ templates for example (where each instance gets compiled into a copy of the template implementation), some usage forms of Template Haskell, etc. There is a tension here, because inlining can be good for performance when it enables specialization.

  • Another parameter is: what information from a module other modules “depend” on. (This matters for incremental compilation: when this information changes, dependent modules need to be rebuilt.) In some languages you can basically depend on all implementation details of other modules, in some you are limited to a form of “interface” that is typically more abstract. (Again, this limits opportunities for inlining/specialization.)

OCaml:

  • offers very few language features based on inlining/specialization (parametric polymorphism never copies code, and even module-level functors are typically not inlined)
  • has a fairly restrictive notion of “interface” (mostly types), along with some implementation-derived details (the .cmx files of the native compiler) with toggles proposed to disable those (the -opaque flag)

I suppose that, for applications embedding massive amount of code, the final linking time may still be high. If we went further in the direction of link-time-optimization, there could be very slow build there as well.

(Some other sources of slow builds are algorithmic inefficiencies in some part of the compiler, in particular the type-checking for module constructs, typically when include is used heavily. Those tend to improve over time, as people writing module-abstractions-heavy program hit these limitations, but it takes difficult work.)

5 Likes

So there’s nothing in particular that’s unique within the OCaml’s compilation pipeline that results in exceptionally fast compilation? Just a collection of parameters and design decisions (separate compilation, compiled interfaces, less specialization, etc…) that allow for less work?

Yes. The same is true for Go.

Also the computation model is simple compared to some languages (e.g. Haskell) and therefore requires less work to be efficient.