Why JIT & AOT has same performance when using Dart in server app?

In flutter application there is a lot of difference between JIT and AOT compilation when running the app, but in server application there is a small difference and sometimes AOT mode is slower than JIT. why this happen? is that means dart for server app is not optimized so much in AOT mode? in which case its good to use JIT mode?

for anyone want to test you can use this repo


Solution 1:

I lead Dart native runtime compilation pipeline development. Kevin's answer is pretty good but I want to add a bit more colour here.

The common perception in Flutter community is that debug Flutter mode is slow because of the JIT and release, this is not entirely true. In reality Flutter framework is filled with large number of very slow consistency checks/assertions which are only enabled in debug mode. That's where the large chunk of slowness is coming from. Disabling these assertions will make this comparison more apples-to-apples.

JIT and AOT have different strengths and weaknesses.

  • AOT is characterised with very fast startup and requires no warmup to reach peak performance. AOT applications use less memory. On the other hand, AOT compiler does not have access to runtime profiling data and thus has to make conservative assumptions.
  • In JIT mode application takes longer to start and requires warmup to reach peak performance. JIT applications use more memory (JIT's own overhead). However JIT also has access to runtime profiling data, which allows it to be more aggressive and more specific in its optimisations - which can allow it to reach higher peak performance.

AOT is great for UIs, because UIs can't tolerate unpredictability and warmup time of the JIT.

JIT is good for batch mode code.

That's basic comparison between AOT and the JIT. The reality is more complicated and nuanced. On paper JIT should better peak performance almost always, but that's not entirely true today. It's highly dependent on the particular code - whether it is going to run faster in AOT or JIT.

In fact we have been somewhat neglecting JIT performance for quite a while now, spending time on AOT performance and code size. There are things (like calls), which are much faster in AOT than JIT.

Hopefully this explains the landscape. I will take a look at your example and provide more in depth response for the specific test case - but this will take some time.

Solution 2:

AOT will be smaller (you can skip the full SDK) and startup faster – no JIT.

An interesting detail: JIT will likely always be faster for long-running processes because the JIT compiler will optimize the code over time using information about how the process is executing.

The AOT compiler does a best-guess optimization given details of the code on disk, but with no runtime information.

We recommend the AOT model for serverless or micro-services that need to cold-start quickly and likely won't run a long time.

If you have services that are long-running or where you really care about maximum possible performance (with less concern for startup time or deploy size) you may want to stick with JIT.

Solution 3:

You are forgetting: ‘dart compile jit-snapshot‘

https://dart.dev/tools/dart-compile