46

It is well known that

If compiling takes even 15 seconds, programmers will get bored while the compiler runs and switch over to reading The Onion, which will suck them in and kill hours of productivity.

Our MonoTouch app takes 40 seconds to compile on Macbook Air in Debug/Simulator configuration.

We have about 10 assemblies in the solution.
We're also linking against some native libraries with gcc_flags.

I'm sure there are ways to optimize compilation time that I'm not aware of, which might have to do with references, linker, whatever.

I'm asking this question in hope that someone with better knowledge than me will compile (no pun intended) a list of tips and things to check to reduce MonoTouch compilation time for debug builds.

Please don't suggest hardware optimizations or optimizations not directly related to MonoTouch.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • 1
    SSD, more RAM, more cores, set up ram disk and compile from there think **ccache** used for android building for example... what OS are you running, it is admittedly too broad a question... – t0mm13b Dec 19 '12 at 23:46
  • 4
    @t0mm13b: Thanks for coming by. The question includes “MonoTouch” in title and I tagged it so as well. MonoTouch is OS X-only product for building iOS apps with C#. Hence I was asking about MonoTouch-specific optimizations, not about hardware / general things. – Dan Abramov Dec 20 '12 at 00:02

3 Answers3

47

Build Time Improvements in Xamarin.iOS 6.4

Xamarin.iOS 6.4 has significant build time improvements, and there is now an option to only send updated bits of code to the device. See for yourself:

Built time improvements
(source: xamarin.com)

Read more and learn how to enable incremental build in Rolf's post.

Evolve 2013 Video

An updated and expanded version of this content can be seen in the video of the Advanced iOS Build mechanics talk I gave at Evolve 2013.

Original Answer

There are several factors affecting build speed. However most of them have more impact on device builds, including the use of the managed linker that you mentioned.

Managed Linker

For devices then Link all is the fastest, followed by Link SDK and (at the very end) Don't link. The reason is that the linker can eliminate code faster than the AOT compiler can build it (net gain). Also the smaller .app will upload faster to your devices.

For simulator Don't link is always faster because there's no AOT (the JIT is used). You should not use other linking options unless you want to test them (it's still faster than doing a device build).

Device tricks

  • Building a single architecture (e.g. ARMv7) is faster than a FAT binary (e.g. ARMv7 + ARMV7s). Smaller applications also means less time to upload to device;

  • The default AOT compiler (mono) is a lot faster than using LLVM compilers. However the later will generate better code and also supports ARMv7s, Thumb2;

  • If you have large assets bundled in your .app then it will take time to deploy/upload them (every time since they must be signed) with your app. I wrote a blog post on how you can workaround this - it can save a lot of time if you have large assets;

  • Object file caching was implemented in MonoTouch 5.4. Some builds will be a lot faster, but others won't be (when the cache must be purged) faster (but never slower ;-). More information why this often happens here).

  • Debug builds takes longer because of symbols, running dsymutil and, since it ends up being larger, extra time to upload to devices.

  • Release builds will, by default (you can turn it off), do a IL strip of the assemblies. That takes only a bit of time - likely gained back when deploying (smaller .app) to the device.

Simulator tricks

  • Like said earlier try to avoid linking since it will take more time and will require copying assemblies (instead of symlinking them);

  • Using native libraries is slower because we cannot reuse the shared simlauncher main executable in such cases and need to ask gcc to compile one for the application (and that's slow).

Finally whenever in doubt time it! and by that I mean you can add --time --time to your project extra mtouch arguments to see a timestamp after each operation :-)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
poupou
  • 43,413
  • 6
  • 77
  • 174
  • That's the kind of answer I was hoping for :-). Thank you Seb! – Dan Abramov Dec 20 '12 at 02:36
  • 2
    I'm glad if it can shave a few seconds from your builds! – poupou Dec 20 '12 at 02:38
  • just wanted to say, fantastic answer. – Eduardo Scoz Dec 21 '12 at 02:43
  • 1
    @poupou If you don't mind, I edited your answer to include a link to Rolf's post on the recent improvements. – Dan Abramov Aug 14 '13 at 13:51
  • @DanAbramov nice addition, thanks! It reminded me that I wanted to update it with a link to my Evolve talk. – poupou Aug 14 '13 at 15:47
  • 1
    It's 2016 now and still it takes me 4-5 minutes to get the app to the device. Just wondering how many hours it would've taken in 2012 then. It's not a small one, granted, but the same application for Android compiles in 30 seconds on the same machine. – Sami Kuhmonen Apr 01 '16 at 07:38
  • I have an app that has 21 MB in the Android Version (according to Google Play). The time it takes to build is around 30s. In Xamarin IOS, the size is around the same, but it clocks at around 5'33, which is *outrageous*. Every time a build happens, and not even a complete overhaul of it. – Eric Wu Nov 28 '16 at 11:48
  • 1
    I'm surprised to know `link all` is actually faster (due to AOT). It saved me **3 minutes** every time I rebuild (from 5 minutes to 1.5 minutes) – Felix Jan 05 '17 at 03:18
4

This is not really meant as an answer, rather a temporary placeholder until there is a better one.
I found this quote by Seb:

Look at your project's build options and make sure the "Linker behavior" is at the default "Link SDK assemblies".

If it's showing "Don't link" then you'll experience very long build time (a large part of it in dsymutil).

I don't know if it is still relevant though, because MonoDevelop shows a warning sign when I choose this option, and it doesn't seem to affect performance much.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
2

You cannot expect your compiler to be lightninng quick without understanding everything that it is required to do. Larger applications will naturally take longer. Different languages or different compilers of the same language can make a huge difference on how long it takes to compile your code.

We have a project that will take almost 2 minutes to compile. Your best solution is to figure out a way to reduce the number of times you compile your code.

Instead of trying to fix 1 line of code and rebuilding, over and over again. Get a group of people together to discuss the problem. Or create a list of 3 or 4 things you want to work on, complete them all then test.

These are just some suggestions and they will not work in all cases.

Jastill
  • 656
  • 3
  • 15
  • 3
    I do understand that compilation takes time. But I don't know enough about MonoTouch ahead-of-time compiler and linker design to tell what takes the most time. Is generating Mono soft debugger instructions time consuming? No? What about running `dsymutil`? Linking against native libraries? Which of the three options should I use for the linker? Does increasing the number of trampolines affect build time? These are the things that make me curious, and I didn't want to test all configurations myself if someone knows the answer. And they *are* specific to MonoTouch, and therefore, are answerable. – Dan Abramov Dec 20 '12 at 00:01