Why is launching `dune utop` so slow?

Compared to the other parts of the toolchain, launching utop via dune feels very slow. Is there any tricks to speed up the process?

What’s happening at the last step that causes such a slow down? It’s always where one very long delay occurs for me (> 10s). Even if my project is fully built.

Comparatively, I found I’m able to get access to a REPL almost instantly with the following commands:

# terminal 1, don't lock the dune file
rg --files | entr -rc dune build

# terminal 2, load a basic REPL with readline support.
# Reload with ctrl+d
while true;do dune top >.ocamlinit && rlwrap ocaml;sleep 0.1;done

Mmm I forgot about another trick, which is to create an .ocamlinit file like such:

$ cat .ocamlinit
#use_output "dune ocaml top";;

Then you just have to launch your REPL this way:

# Just one terminal. Reloads and recompiles via ctrl+d
while true;do utop;sleep 0.1;done

This works well for simple projects and loads a bit slower than the first technique but still fast enough (~2s)

So that makes me wonder what’s the use case for the command dune utop?

I have not noticed the slow startup. In any case, my use case for “dune utop” is that it takes care of loading an entire project into utop. Doing this manually is quite tedious.

dune utop was available a few years before #use_output "dune ocaml top";;. It actually links all the code together in a binary, which can be slower than loading modules in the default repl, but is much faster when the codebase is large.

1 Like

We are talking about linking of bytecode libraries, right? I’m not sure why this would be noticeably slower or faster than loading modules in the toplevel, which I assume uses Dynlink internally.

I filed a related issue back in January.

1 Like

I don’t have actual numbers to provide, I thought it was an expected difference. But I could try to gather something.

By having a quick look I also found another difference, #use_output "dune ocaml top" in utop gets me an error. This is on ahrefs’ codebase, don’t have a small repro yet.

utop # #use_output "dune ocaml top";;
File "(command-output)", line 1:
Error: Reference to undefined global `Dune_site__Dune_site_data'

On Revamp dune utop for greater speed · Issue #6894 · ocaml/dune · GitHub , @rgrinberg says that they don’t know of a strong reason to keep the current dune utop implementation instead of using the faster dune ocaml top. (Note: this is different from @Khady’s experience above that dune utop is sometimes faster. Why?)

My understanding is that anyone would be welcome to work on replacing the current dune utop implementation by something better – with the risk of having to fix bugs along the way, or of finding out that it does not work for a good reasons we don’t know yet. Any volunteer? ( @benjamin-thomas ? )

Thanks for the feedback, it makes sens now.

I could try. I was unsuccessful in bootstrapping the project however (I get compilation errors), so I may need a bit of guidance to get started and become a bit of a burden.

Let me know if me giving it a try sounds interesting to you @rgrinberg

(Probably thanks to the feedback in this Discuss thread,) @nojb improved the speed of dune utop in dune utop: do not do custom linking by nojb · Pull Request #8631 · ocaml/dune · GitHub , which is now merged and should be part of the upcoming dune 3.11 release. On the project ocamlformat, launching dune utop goes from 10s to 3s on his machine.

This sounds like “case closed” to me – but there may be other possible optimizations, I don’t know.

1 Like

Thanks @gasche for the ping; I actually had missed this discussion and only learned about it from the Github issue filed by @grayswandyr. Perhaps @benjamin-thomas can try the curren (unreleased) version of Dune and report back here if it improves things (hopefully it will!).


Sounds fantastic, many thanks!

I would have loved to try out the unreleased version, but as I said I can’t get the project bootstrapped :frowning:

Either I’m doing something dumb, or the file doc/hacking.rst needs an update.

I get this error FYI, launching make dev from within a nix shell.

File "src/dune_rules/setup.ml", line 3, characters 26-55:
Error: Unbound module Install.Section.Paths

I didn’t have better luck trying to bootstrap from a vscode dev container, nor from my host OS (Ubuntu 20.04)

You should be able to do it by typing opam pin --dev dune.


1 Like

The compilation speedup is very noticeable for me. Whereas before I would have to wait about 12-13s to access the REPL on a simple project but an oldish computer, now I can access it in 3-4s.

Thanks again!