javagraalvmgraalvm-native-imageahead-of-time-compile

Does using quick build mode for tests change functionality?


I have an application that is deployed using GraalVM's native-image tool. In the CI pipeline of that application, I am running my tests (including integration tests) in JVM mode and (assuming they succeed in JVM mode) also in native mode (using native-build-tools) in order to ensure native-image doesn't break anything (e.g. due to missing reflection metadata).

However, compiling these tests takes quite some time time and build resources (e.g. memory) which I would like to reduce if possible.

In the documentation of native-image, I can see the following about the quick build mode:

Consider using the quick build mode (-Ob) to speed up your builds during development. More precisely, this mode reduces the number of optimizations performed by the Graal compiler and thus reduces the overall time of the compilation stage. The quick build mode is not only useful for development, it can also cause the generated executable file to be smaller in size. Note, however, that the overall peak throughput of the executable may be lower due to the reduced number of optimizations.

From my testing, this can improve build performance significantly. However, I am worried about it being possible that native-image omitting some optimizations in quick build mode that could break some functionality (e.g. where I need to add some reflection/resource/JNI/proxy hints that may be necessary with -O3 but not with -Ob for some reason).

Will quick build mode for (CI) tests change any functionality in a way that could break my tests?

Ideally, I would like to see reasoning (why it is (not) safe) including references to documentation (if possible) about this.


Solution

  • Is it generally considered safe to use quick build mode for (CI) tests?

    In general: Yes.

    Ideally, I would like to see reasoning (why it is (not) safe) including references to documentation (if possible) about this.

    If we look at the source code [1] of native image we see that passing in -Ob only impacts how the compiler is configured, so - barring any bugs in the compiler - a native image built with -Ob and without it should be the same regarding features and behaviour but different in terms of performance (as stated in the docs you posted in your question).

    [1] https://github.com/oracle/graal/blob/master/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java#L307