Gradle Profiler / View / View Binding

View Binding: Performance

In September 2019 Google released Android Studio 3.6 Canary 11 to the Canary channel. This had an interesting new addition: View Binding. In this short series we’ll take a look at how it works, and what impact it may have on performance.

Now we come to the important one for many teams: build performance. When I first discussed View Binding with some of my colleagues at Babylon Health this was the first question that many of them asked. We have quite a large, complex project with a number of build flavors. Consequently our CI builds can take a while, so we are have to balance whether new features will justify any increases in our build times, and if there are any optimisations that we can do to mitigate any increases. My colleague Antonis Tsiapaliokas suggested using Gradle Profiler to benchmark the impact on build times. Many thanks to Antonis for this most excellent suggestion.

It is worth pointing out that the actual times in the following benchmarks are not meaningful on their own. The important thing is how the numbers change. This benchmarking wasn’t done on a particularly optimised build machine, but if you wish to perform your own benchmarking this to see how it affects your CI build speeds, then I would suggest performing the benchmarking on your CI. Also, it is worth benchmarking full builds because generated code may have more of an impact on your overall build time than just the code generation itself. For example additional classes will increase your proguard times, so be sure you include proguarding in your benchmark runs if that’s a part of your full build

Gradle Profiler works by running a number of warm-up builds, followed by a number of measured builds. I have opted for the default of 6 warm-up builds followed by 10 measured builds. The report generated gives the stats of these 10 measured builds, and as a control sample I initially benchmarked a simple project with a single layout:

1 LayoutNo View Binding
Time (ms)
View Binding
Time (ms)
mean9150.29073.5
min8138.08291.0
25th percentile8794.758815.25
median9216.09019.0
75th percentile9543.59389.0
max9847.09850.0
stddev544.2501059051599630.9507464489161

There’s really not much difference here, but I realise that the majority of sample code projects that I publish alone with my blog posts are not particularly representative of most projects. They are designed to be small and focused on a single thing. To give a more representative view of how View Binding might affect builds in real projects, I took one of the more complex layouts (containing 10 child Views) from here, and then duplicated it within a simple project to simulate a project with a much larger number of layouts. I have then benchmarked build with View Binding both enabled and disabled so that we can get a feel for how it affects out build time.

Fist I went with 100 duplicate layouts:

100 LayoutsNo View Binding
Time (ms)
View Binding
Time (ms)
mean8912.311346.6
min8274.010137.0
25th percentile8645.7510308.5
median8920.010811.5
75th percentile9205.012855.0
max9707.013451.0
stddev400.792562029009961296.815261408587

The times without View Binding are similar to those for a single View so the addition of these extra Views does not have a noticeable impact on the base build time. However the times with View Binding are 1-4 seconds longer. While there is a bit of variance here, I don’t think that even the worst case of 4 seconds will have a major impact on most projects.

Some simple mathematics (comparing the differences of the metrics in the table, and dividing by the number of layouts) suggests that for a layout containing 10 child Views View Binding is adding between 14-40ms to our build time. That’s actually pretty trivial.

Rather than leave it there, I thought it worth going to an extreme and increasing the number of layouts to 1000:

1000 LayoutsNo View Binding
Time (ms)
View Binding
Time (ms)
mean14392.328565.2
min11826.023028.0
25th percentile12390.524577.25
median14420.029119.0
75th percentile15832.7531378.25
max17015.037072.0
stddev1776.48404627417544279.422775198646

There are a couple of things worth mentioning here. Firstly the build time without View Binding enabled has increased due to the number of layouts in the project. While this is not by a significant amount – between 2 and 7 seconds – it does indicate a noticeable change in build complexity. The second thing worthy of note is that the View Binding has increased the build times quite significantly as well. However, if we apply the same mathematics as before, it is still only around 12-20ms per layout – so this is actually pretty consistent. Compared to the 100 layouts benchmark, the larger number of samples here would suggest that 12-20ms is a more accurate value than the 14-40ms we got for the smaller sample size.

It is also worth considering that these tests are purely to show the raw impact that View Binding has on the build time. In a real project with 1000 layouts there would be an awful lot more source code, third-party libraries, annotation processing, and all the rest, so build times would be considerably longer than they are for this project. In such cases I doubt whether an extra 12-20 seconds added to the build would actually slow it down by a noticeable amount. These tests have been designed without using incremental builds, so the impact on bugfix -> build -> test -> rinse -> repeat cycles should be negligible.

Of course, all projects are different, and the impact of View Binding on build times will vary from project to project. However, my investigations have given me confidence that the benefits significantly outweigh the small build time hit. So you can expect to see all of my blog post support code using this henceforth!

The source code for this article including the results of the Gradle Profiler runs (in the /profile folder) can be found here.

© 2019 – 2020, Mark Allison. All rights reserved.

Copyright © 2019 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

4 Comments

    1. That is difficult because they cannot be turned off so there is no way, that I’m aware of, to measure the impact they have on build speeds.

  1. Thank you so much for your performance tests. I have one theoretical question though.

    Everyone states, that ViewBinding does not use annotation processing, but as you may see it uses code generation still. What is the difference between those two and why annotation processing is so much worse?

    1. The simple answer is that annotation processing is slow, and has a major effect on build times in large projects.

      Code generation and annotation processing are two very different things. Annotation processing will analyse both the source and compiled code, and individual plugins can behave in varied ways depending upon that. Code generation is the process of creating code at build time based upon external constraints.

      In many cases, annotation processor plugins will perform code generation. Dagger / Hilt are examples of this: They generate code based on annotations in the project code.

      View Binding does not use annotation processing at all. Instead, it generates the binding code by analysing the layout XML files.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.