Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Tips to reduce android build times. #643

Closed
timbotimbo opened this issue Jul 2, 2022 · 11 comments
Closed

[Android] Tips to reduce android build times. #643

timbotimbo opened this issue Jul 2, 2022 · 11 comments

Comments

@timbotimbo
Copy link
Collaborator

timbotimbo commented Jul 2, 2022

With recent Unity versions (2020, 2021 and 2022) Flutter Android builds will take a lot longer, because it also has to compile the IL2CPP code from Unity.

From the Readme:

  • Android builds takes forever to complete Unity 2022.1.*, remove these lines from unityLibrary/build.gradle file

    commandLineArgs.add("--enable-debugger")
    commandLineArgs.add("--profiler-report")
    commandLineArgs.add("--profiler-output-file=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_conv.traceevents")

Here is some testing to check how to speed things up.

Unity settings

IL2CPP Code Generation

  • Build Settings -> IL2CPP Code Generation: select Faster (smaller) builds instead of Faster runtime.
  • Or C# EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;

C++ compiler configuration

  • In Player settings -> Other settings -> configuration, select Debug.
  • Or C# PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);

Disable script debugging

Don't bother setting this in the Unity settings, it will be overridden by the build script.
Assets/FlutterUnityIntegration/Editor/build.cs
In the function DoBuildAndroid() remove the line enabling script debugging.
playerOptions.options = BuildOptions.AllowDebugging;
This is the same as removing commandLineArgs.add("--enable-debugger") from the build.gradle file after an export.

Measuring results

When you run a Flutter build, there are multiple IL2CPP stages that report their duration, with 2 sections taking far longer than all others.
We can compare these build durations when using different settings in Unity.

Log of the slow armv7 and arm64 sections
Starting: Z:\fuw20221.1.0+7\2021\example\android\unityLibrary\src\main\Il2CppOutputProject\IL2CPP\build\deploy\bee_backend\win-x64\bee_backend.exe --profile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/backend_profiler1.traceevents" --stdin-canary --dagfile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/bee.dag" --continue-on-failure --dagfilejson="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate/bee.dag.json" FinalProgram
WorkingDir: Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_armeabi-v7a_Release/il2cpp_cache/buildstate
ExitCode: 0 Duration: 2m:04s
Build succeeded with 553 successful nodes and 0 failed ones

Starting: Z:\fuw20221.1.0+7\2021\example\android\unityLibrary\src\main\Il2CppOutputProject\IL2CPP\build\deploy\bee_backend\win-x64\bee_backend.exe --profile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/backend_profiler1.traceevents" --stdin-canary --dagfile="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/bee.dag" --continue-on-failure 
--dagfilejson="Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate/bee.dag.json" FinalProgram
WorkingDir: Z:/fuw20221.1.0+7/2021/example/android/unityLibrary/build/il2cpp_arm64-v8a_Release/il2cpp_cache/buildstate
ExitCode: 0 Duration: 2m:03s
Build succeeded with 553 successful nodes and 0 failed ones

Results

The exact durations here aren't important, as this will be different of every computer and project setup.
This is after flutter clean and a fresh Unity export. Any subsequent runs will be faster because of caching.

Flutter build apk, with an export from Unity 2021.3.5f1 in android/unityLibrary on Windows 10.

Setting armv7 duration arm64 duration
example project 2m:04s 2m:03s
1 - Code generation (faster builds) 1m:41s 1m:38s
2 - Compiler configuration (debug) 45s 43s
3 - No script debugging 30s 30s
1 + 2 35s 34s
1 + 2 + 3 23s 25s

Conclusion

My advice is to add this to the build script in DoBuildAndroid() for any test or debug builds, remove it for final release builds.

//Assets/FlutterUnityIntegration/Editor/build.cs
#if (UNITY_2020_3_OR_NEWER)
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);
    EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;
#endif

If it doesn't affect your workflow, disable script debugging.

// playerOptions.options = BuildOptions.AllowDebugging;

And if you are developing on an arm64 device anyway, temporarily remove the armv7 build target from the Unity player settings.

@RoyalCoder88
Copy link
Collaborator

Wow @timbotimbo , I followed your steps and I reduce the time from ~15min to 3min...thanks!

@jamesncl
Copy link

jamesncl commented Jul 6, 2022

Thanks @timbotimbo this should probably be added to the README for advanced users, but with an extra big warning to remove the changes for a release build. Just to add a bit more info from the Unity docs:

Il2CppCodeGeneration

There are two options for IL2CPP code generation. Il2CppCodeGeneration.OptimizeSpeed generates code that is optimized for runtime performance. This is the default and the behavior in previous versions of Unity. Il2CppCodeGeneration.OptimizeSize generates code that is optimized for build size and iteration. It generates less code and produces a smaller build but may have an impact on runtime performance, especially for generic code. You should consider this option when faster build times are important, such as when iterating on changes.

Il2CppCompilerConfiguration

Debug configuration turns off all optimizations, which makes the code quicker to build but slower to run.

Release configuration enables optimizations, so the compiled code runs faster and the binary size is smaller but it takes longer to compile.

Master configuration enables all possible optimizations, squeezing every bit of performance possible. For instance, on platforms that use the MSVC++ compiler, this option enables link-time code generation. Compiling code using this configuration can take significantly longer than it does using the Release configuration. Unity recommends building the shipping version of your game using the Master configuration if the increase in build time is acceptable.

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 10, 2022

Thanks @timbotimbo this should probably be added to the README for advanced users, but with an extra big warning to remove the changes for a release build. Just to add a bit more info from the Unity docs:

Il2CppCodeGeneration

There are two options for IL2CPP code generation. Il2CppCodeGeneration.OptimizeSpeed generates code that is optimized for runtime performance. This is the default and the behavior in previous versions of Unity. Il2CppCodeGeneration.OptimizeSize generates code that is optimized for build size and iteration. It generates less code and produces a smaller build but may have an impact on runtime performance, especially for generic code. You should consider this option when faster build times are important, such as when iterating on changes.

Il2CppCompilerConfiguration

Debug configuration turns off all optimizations, which makes the code quicker to build but slower to run.

Release configuration enables optimizations, so the compiled code runs faster and the binary size is smaller but it takes longer to compile.

Master configuration enables all possible optimizations, squeezing every bit of performance possible. For instance, on platforms that use the MSVC++ compiler, this option enables link-time code generation. Compiling code using this configuration can take significantly longer than it does using the Release configuration. Unity recommends building the shipping version of your game using the Master configuration if the increase in build time is acceptable.

Should I add this to our unitypackage? So that we improve android build?

@timbotimbo
Copy link
Collaborator Author

timbotimbo commented Jul 10, 2022

@Ahmadre
Given that playerOptions.options = BuildOptions.AllowDebugging; also causes crashes with Unity 2022 (#629 ), you should probably comment that line out in DoBuildAndroid for the next unitypackage. That way people can always enable it again if they want to experiment.

The other 2 might be better off in the readme, because its better to disable them again for release builds.

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 11, 2022

@Ahmadre Given that playerOptions.options = BuildOptions.AllowDebugging; also causes crashes with Unity 2022 (#629 ), you should probably comment that line out in DoBuildAndroid for the next unitypackage. That way people can always enable it again if they want to experiment.

The other 2 might be better off in the readme, because its better to disable them again for release builds.

I tested everything with Unity 2021.* and 2022.* and there're some API-changes, actual solution looks like:

#if UNITY_2020_3_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);
    EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;
#elif UNITY_2022_1_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);
    PlayerSettings.SetIl2CppCodeGeneration(UnityEditor.Build.NamedBuildTarget.Android, UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize);
#endif

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 11, 2022

I will update this in Build.cs and add a note to README. Thank you so much @timbotimbo :)

@timbotimbo
Copy link
Collaborator Author

timbotimbo commented Jul 11, 2022

@Ahmadre

#elif UNITY_2022_3_OR_NEWER

Shouldn't that be UNITY_2022_1 or something, I don't think we're at 2022.3 yet.

EDIT:
The change is listed here in the changelog for 2022.1 https://unity3d.com/unity/whats-new/2022.1.0

MIght also make more sense to switch the if statement around.

#if UNITY_2022_1_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);
    PlayerSettings.SetIl2CppCodeGeneration(UnityEditor.Build.NamedBuildTarget.Android, UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize);
#elif UNITY_2020_3_OR_NEWER
    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);
    EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;
#endif

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 11, 2022

@Ahmadre

#elif UNITY_2022_3_OR_NEWER

Shouldn't that be UNITY_2022_1 or something, I don't think we're at 2022.3 yet.

EDIT:

The change is listed here in the changelog for 2022.1 https://unity3d.com/unity/whats-new/2022.1.0

MIght also make more sense to switch the if statement around.

#if UNITY_2022_1_OR_NEWER

    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);

    PlayerSettings.SetIl2CppCodeGeneration(UnityEditor.Build.NamedBuildTarget.Android, UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize);

#elif UNITY_2020_3_OR_NEWER

    PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Android, Il2CppCompilerConfiguration.Debug);

    EditorUserBuildSettings.il2CppCodeGeneration = UnityEditor.Build.Il2CppCodeGeneration.OptimizeSize;

#endif

Oh thank you! Sure It's UNITY_2022_1_OR_NEWER :)

@jamesncl
Copy link

jamesncl commented Jul 13, 2022

Because these changes actually reduce the performance of Unity, I would suggest having an extra menu option to build with these options. Otherwise, we are degrading the performance of people's apps as default and in an unexpected way. It would also be really easy to forget if you have manually changed these settings yourself. So in this menu:

image

Instead of 'Export Android', there would be 'Export Android (release)' and 'Export Android (debug)' options - release just does the normal (slow, optimised) build and debug does the faster, unoptimised build.

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 15, 2022

Because these changes actually reduce the performance of Unity, I would suggest having an extra menu option to build with these options. Otherwise, we are degrading the performance of people's apps as default and in an unexpected way. It would also be really easy to forget if you have manually changed these settings yourself. So in this menu:

image

Instead of 'Export Android', there would be 'Export Android (release)' and 'Export Android (debug)' options - release just does the normal (slow, optimised) build and debug does the faster, unoptimised build.

Yes! That's a better idea :) Will do that as soon as I've got time!

@Ahmadre
Copy link
Collaborator

Ahmadre commented Jul 16, 2022

Bildschirmfoto 2022-07-16 um 23 11 03

I added a new parameter internally (isReleaseBuild) and reused the code.

I will upload it now to master channel and update unitypackage and merge another PR and release another version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants