Using Mono AOT to speed up Editor Scripts

Briefly, I want to know if there is a way to use Mono’s AOT to improve the startup time of Editor scripts.

I work on the Arcadia project, which requires a very large assembly to function (Clojure.dll, the entire Clojure language and standard library). Our problem is that whenever Unity reloads Mono, Clojure.dll is reloaded as well, and it can take a bit of time, 8-30s in the worst cases. This isn’t a problem in an exported game, but it makes the Editor experience clunkier than we’d like. Clojure is needed in the editor because much of Arcadia is written in the Clojure language, and it powers the REPL which provides our live coding experience.

Outside of Unity on Mono 4.6, loading Clojure takes about 2.5 seconds. This still isn’t great, and we suspect the difference to be because of Mono versions, but without knowing exactly how Unity loads assemblies its hard to say if we’re doing something that might be throwing it off.

If we AOT our assemblies according to Mono’s instructions, our start time goes down to 0.3 seconds! When an assembly is loaded, Mono will check if a .dylib file with the same name exists besides it with the pre-JIT’ed code and will load that instead, skipping the initial JIT step and significantly improving startup time. The original assembly is required as it contains all the metadata.

We don’t see the same speedup in Unity. Any theories as to why this might be the case? Does Unity use Mono’s Assembly loader? Does it ignore .dylib files? Is there a way to get it to load them at all? This would be a major improvement to our users’ experience.

Thanks!

Some progress: running Unity with MONO_LOG_LEVEL=info reveals that it is trying to load dylib files for every assembly.

Here’s it trying and failing to find a .dll.dylib file

Mono: Assembly Microsoft.Scripting.Core 0x127a08fd0 added to domain Unity Child Domain, ref_count=1

Mono: AOT failed to load AOT module /Users/nasser/Projects/arcadia/Assets/Arcadia/Infrastructure/Microsoft.Scripting.Core.dll.dylib: dlopen(/Users/nasser/Projects/arcadia/Assets/Arcadia/Infrastructure/Microsoft.Scripting.Core.dll.dylib, 9): image not found

And here it is finding a Clojure.dll.dylib file I prepared using mono --arch=64 --aot

Mono: Assembly Clojure 0x127a06920 added to domain Unity Child Domain, ref_count=1

Mono: AOT module /Users/nasser/Projects/arcadia/Assets/Arcadia/Infrastructure/Clojure.dll.dylib has wrong file format version (expected 66 got (null))

Mono: AOT module /Users/nasser/Projects/arcadia/Assets/Arcadia/Infrastructure/Clojure.dll.dylib is compiled against runtime version '(null)' while this runtime has version '2.6.5 (tarball)'.

I prepared the files using Mono 4.8 My guess is that the dylib format is different enough that its breaking. Going to try and AOT from Mono 2.6.