📜 ⬆️ ⬇️

Android application performance

Mobile application performance is a key issue, regardless of the platform in question. We talked with Alexander Efremenkov about the specifics of this problem under Android, including from the perspective of switching from the Dalvik virtual machine to ART.



- Tell a few words about yourself and your work. What is the role of performance experiments with Android?

Alexander Efremenkov: I work in Yandex, where I am developing a Yandex.Taxi taximeter.
')
The specificity of our project is different from the usual entertainment-solutions. The service provides the interaction of two parties: at one end of the “wire” there is a user with the front of the Taxi application, and at the other end, the user of the taximeter. And in the course of the interaction, both parties should get the expected result.

The project is complicated primarily because of the large number of arithmetic necessary for calculating tariffs. At the same time, the requirements for stability are very serious: we just have to provide drivers with a high-performance and reliable code. In ordinary applications, where it is possible, conditionally speaking, to look at kittens, such requirements are not particularly relevant.
In my free time I do research on the internal features of Android, in particular, how it differs from the environment of the parent JDK.

- What performance rakes do you most often encounter at work? Where does the search for the sources of problems begin?

Alexander Efremenkov: Details, of course, under the NDA. But I can say that most of the performance problems are due to the choice of algorithms in the already written code. In this case, the first stage of the search for bottlenecks, as a rule, is the search for problems in the written code, and the second stage is to bypass the runtime problems.

- Is there any root cause of the problems that determine the complexity of the struggle for productivity in Android?

Alexander Efremenkov: The problem is that in most cases, developers think that runtime optimization (JIT / AOT) in Android works the same way as in JDK. But it is not.
There are a number of differences, and we need to somehow live with it. And for this you need to understand the insides of the Android runtime. You have to understand how to get adequate performance metrics, how to compare hand-written constructions in order to understand which one to choose for production.

- Can you give any examples of the differences mentioned?

Alexander Efremenkov: A good example is to optimize the release of a large number of identical exceptions. JDK is able to optimize the emission of identical exceptions by displaying only a throwable message without constructing a spectra (the formation of a spectra is quite a difficult operation ). Dalvik / ART does not use this trick and honestly caches the call stack for its subsequent printout.

Also worth mentioning is the dead code elimination in Android. In most cases, it simply does not exist, while in the JDK this optimization is quite common.

Another interesting difference is the AOT compilation, which allows you to optimize and save machine code, as well as dump / deploy AOT sections to disk and from disk.
These and other points must be considered in the work to improve the performance of the application.

- What should work on the performance of an application for Android ever begin with?

Alexander Efremenkov: From measurements. The first step to performance is flame graphs, and after that there should be optimization of bottlenecks.

By itself, optimization of bottlenecks is precisely in the ideal case of rewriting these places so as to fall under the runtime optimization, and not fall into deoptimization. Those. After the next manipulations with the code, it is necessary to measure the rewritten prototype under different conditions.

- What is the situation with the measurements? Since productivity as such is the object of research, does the average developer “out of the box” “squeeze the maximum” out of the box without understanding the details?

Alexander Efremenkov: On average, the situation with measurements is as follows: first, the developer resorts to tracing and searching for bottlenecks using a ready-made flame graph. After receiving some results, he rewrites his code in those places where a long cpu time was revealed. In this case, the final version of the code is often chosen empirically from several attempts (which variant shows itself better in the mentioned measurements — the one used).
The complexity of this situation is in the absence of a “systemic” approach. Typically, problem solutions are validated in a similar way by a small number of extreme cases. And this raises the question of the compliance of the measurements with the original task.

- It turns out that the measurement tools built into the Android SDK do not provide the necessary information?

Alexander Efremenkov: Unfortunately, the Android SDK tools provide a sufficient amount of information only about the executable code, and not about what optimizations are used within the Android runtime. For example, you cannot get information about why ART is optimized when you call getter / setter and removes unnecessary checks for null, and why Dalvik does not always do these optimizations. With conventional tools, such implementations of behavior and optimization are simply impossible to see - only if you are a runtime developer yourself and have relevant knowledge.

- What tools are most missing in the Android SDK?

Alexander Efremenkov: The Android toolkit is currently undergoing many changes due to the progressive evolution of the platform - the transition from Dalvik to ART.
At the moment, there is no adequate tool for creating benchmarks. This problem also defines the approach to measurements described by me earlier. The developer is forced to write as his heart tells him. And he cannot conduct an adequate experiment due to the lack of tools. The only thing left for him to do is to wrap the method call in try finally, which measures this call with two time stamps: initial and final. But, unfortunately, the results of experiments of this kind cannot be fully relied upon.

- What exactly is the problem of such experiments?

Alexander Efremenkov: The problem in measurements through try finally (that is, with two time-steps) is described by two theses:


Often the problem is solved by the law of large numbers: the call is run n times and the total time of the call is divided by n.

- Is it possible to solve this problem with third-party tools?

Alexander Efremenkov: At the moment, it’s difficult to solve the problem of accurate measurements with third-party tools, because Now these tools work under JDK (for example, JMH).

But the situation is gradually changing. By the way, my own development is nearing completion - its port, AMH - Android Microbenchmark Harness, which takes into account the specifics of Android Dalvik / ART.

- Is the situation with optimization in Dalvik / ART the same? Or, with the transition to ART, living, conditionally speaking, has become better?

Alexander Efremenkov: As I mentioned above, Dalvik and ART are fundamentally different: they use different optimizations and, accordingly, give completely different end results.

Of course, with the transition to ART it became better to live. At least the regressive holes of some applications have closed this. However, ART solves the problem of primary AOT compiling, but it does not solve subsequent compilation problems on the fly. One way or another, runtime needs information and some “warming up” in order to understand what AOT / JIT optimization to perform, and whether it can be performed at all.

- What will you advise our readers instead of a conclusion as part of a set of experience in the field of performance under Android?

Alexander Efremenkov: I can only give one advice: you need to write code and try to understand how it works. And in any incomprehensible situation it is necessary to refer to the source code of the platform in order to understand what exactly is going on inside. Otherwise, there is a risk to build air locks in your head with inaccurate information that may eventually collapse due to ignorance of the platform features (especially since these features differ due to platform fragmentation).

If you are also interested in other aspects of the development of applications for Android and iOS - we hasten to invite to our conference for the developers of Mobius 2017 , which starts this Friday 21.04.

Source: https://habr.com/ru/post/326848/


All Articles