Actualité

Google says R8 can make Kotlin coroutines up to twice as fast on Android

Google has detailed an R8 optimization that can accelerate Kotlin coroutine launches and cancellations, with the largest reported gains appearing in Jetpack Compose workloads.

Image éditoriale de démonstration montrant des smartphones sur un banc de test radio
Les images de démonstration sont signalées et ne remplacent jamais une preuve produit.

Google has published a technical update describing how its R8 optimizer can make important Kotlin coroutine operations up to twice as fast on Android. The change targets atomic field access used by kotlinx.coroutines, and is available when developers use Android Gradle Plugin 9.2.0 or R8 9.2.0 directly.

The announcement matters because Kotlin and coroutines are now central to a large share of Android application development. Coroutines let apps perform asynchronous work without blocking the user interface, from loading network data to reacting to gestures and updating screens. They are also deeply embedded in Jetpack Compose, Google’s modern toolkit for building Android interfaces.

Where the overhead came from

According to the Android Developers Blog, the performance investigation began with Compose workloads that repeatedly launch and cancel coroutines. In one example, the team found that about 80% of the time spent creating and updating Modifier.clickable was consumed by internal coroutine launches and cancellations rather than by the visible interaction itself.

The underlying cost was linked to AtomicReferenceFieldUpdater, a Java mechanism used by the atomicfu library to implement lock-free operations. Each operation performs reflective checks to confirm that the target field and object are valid. A single check is inexpensive, but coroutine lifecycles can perform many atomic operations, allowing the overhead to accumulate across common UI interactions.

How the R8 change works

Google’s engineers added a compiler transformation that introduces field offsets alongside updater fields. When R8 can prove that an updater, its holder object and the new value meet the required type conditions, it replaces the reflective updater call with a direct operation through Unsafe. The result avoids repeated runtime validation while preserving the original path when static analysis cannot safely prove that the replacement is valid.

The process also includes cleanup. If every call site can use the optimized form, R8 can remove the original updater field and its initialization code. If only some sites qualify, the remaining calls continue to use the original implementation. That selective approach is important for application compatibility: the optimization is applied where the compiler can establish that the behavior remains safe.

What Google measured

Google reports that optimized uses of atomicfu can reach performance comparable to AtomicReference, and can be faster in some benchmarks. The clearest result appeared in Jetpack Compose’s coroutine microbenchmarks. After the tests were updated to a newer R8 version, launching and cancelling coroutines inside LaunchedEffect became up to twice as fast in the reported workload.

The same post also notes that the Android Runtime team is working on similar optimizations at the virtual-machine level. On devices targeting API level 36 and running recent Android software, some applications may already receive related benefits through runtime and JIT improvements. Google reports an approximately 15% improvement in the referenced coroutine benchmarks after those ART updates, although the result depends on the device and the code path being measured.

What developers need to know

The practical step is straightforward: developers can upgrade to AGP 9.2.0 or use R8 9.2.0 directly. The change is applied during optimization, so applications do not need to rewrite their coroutine code to benefit from the transformation. Teams should still run their normal release tests after a build-tool upgrade, particularly if they rely on custom shrinker rules, reflection-heavy libraries or unusual bytecode patterns.

Developers should also avoid treating the headline result as a universal promise. The published improvement concerns specific atomic operations and benchmarked coroutine paths. It does not mean every Android app will launch twice as quickly, nor that all screens will render twice as fast. Apps with little coroutine activity, limited R8 optimization or different performance bottlenecks may see a smaller change.

The broader significance is that Android performance work is increasingly moving into the build and runtime toolchain. Developers can gain measurable responsiveness improvements without adding another library or changing the application’s visible design. For apps that use Kotlin coroutines heavily, especially Compose interfaces with frequent interaction and animation work, the new R8 behavior gives the latest Android toolchain a concrete reason to be evaluated in the next release cycle.

Sources et éléments vérifiables

Official source: android-developers.googleblog.com (s’ouvre dans un nouvel onglet)