Running on a release build improves performance a ...
# compose
z
Running on a release build improves performance a lot as expected. But what are the actual flags that make the difference? Im trying to create a build type thats as close to debug as possible, while having the performance of a release build (to prevent a nasty IDE/OS bug that steals a few hours a day).
My current build types are as follows, where staging and release both help with performance. Staging is just a semi-release thats faster to build with, but (if possible) Id like to make it closer to debug to hopefully sort the nasty issue out. Performance sucks if I do initWith debug, but Im sure there are other flags that I can specify?
Copy code
buildTypes {
    debug {
        minifyEnabled false
        shrinkResources false
        crunchPngs false
        signingConfig signingConfigs.debug
    }

    release {
        minifyEnabled true
        shrinkResources true
        signingConfig signingConfigs.release
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), '<http://proguard-rules.pro|proguard-rules.pro>'
    }

    staging {
        initWith release
        minifyEnabled false
        shrinkResources false
        crunchPngs false
    }
}
e
minifyEnabled
enables R8 to strip out calls which provide more information for debugging but add overhead: https://github.com/androidx/androidx/blob/androidx-main/compose/runtime/runtime/proguard-rules.pro
s
In general, you want to keep R8, but disable certain optimizations that might be slower to compile Compose might also automatically enable source information/live literals for debug builds, but not sure if Gradle DSL has automatic configuration for this
j
ART is going to tank performance for debug builds, too.
a
What do you mean by "as close to debug as possible"? If you want it to be debuggable, you won't be able to get release build performance.
z
@ephemient & @shikasd It seems that I can get away with not using R8 at all for staging builds. At least I cant tell the difference between it and release in terms of performance. @jw & @Albert Chang Yeah, I dont really want a pure debug build because of this. The issue always points to mergeDexStaging and its resulting classes.dex being locked/used by another process. That task doesnt exist in debug builds at all, but I dont know what role it plays for release (in terms of compose performance and all of that jazz) and whether or not I can get around it?
c
The biggest difference I've seen is setting isDebuggable = false in my debug release variant. This has been faster than switching to a release build. So although I know r8 should help a lot, in my anecdotal testing... isDebuggable basically gets me 99% of the perf improvement. Ymmv and of course it's good to know that it's just a shortcut because producing a release build for my one project is a pain.
z
New hope! Thank you @Colton Idle, Ill try that out. Given that debug builds work pretty well in terms of the issue, hopefully this is the in-between Im looking for 🙂
That helped, a lot! I still get the issue occasionally, but it now points to a different set of files that arent generated as frequently (and Im already looking into disabling their task as its lint related). I really appreciate it, this is just straight up 1-2 more hours of productive coding in a day, maybe even more. Thank you @Colton Idle 🙏🏽
c
Yeah, my team is going to work on getting release builds easier to switch to. But for now that flag helps a lot.
This also helps in case the issue is your signing key. Basically it allows you to create a release build with debug signing key when invoked from ide
Copy code
release {
  signingConfig =
      if (properties.containsKey("android.injected.invoked.from.ide")) {
        signingConfigs.getByName("debug")
      } else {
        signingConfigs.getByName("release")
      }
...
z
Oh, thats neat! I use the "debug release" build like 99,9% of the time locally and its signed with a debug key - so no issues there! Do you switch to a full on release build often? We probably have very different workflows, but Im still curious on why you would want to do that?
c
not really. but having that code allows our dev team to switch to release mode to try debugging an issue (lets say an R8 failure on our CI) locally. and then every dev also doesn't need to have the actual release signing key and passwords on their local machine.