📜 ⬆️ ⬇️

Android SDK vs NDK - comparing the performance of similar types of code

In order to improve the performance of the application, Android began to gradually rewrite critical sections of code from Java (SDK) to C ++ (NDK). The result turned out to be comparable with the fact that I received a couple of decades ago, making assembly inserts into the turbo-patch code.

I do not set myself the task of describing work with the Android NDK - the experience itself is not enough. Those who are interested, it is better to start with this link.
The purpose of this short article is to give a few numbers, which I obtained experimentally, comparing the execution time of certain functions written in Java and then rewritten in C ++. And, probably, these figures motivate someone to study this question more deeply.

Since my application is related to the processing of photographs, the bottlenecks were cycles of traversing the pixels of the image and certain actions on them. I tested on real devices - Nexus One and Nexus 7 (2012). The results of the experiments (in ms) are tabulated:

Layer overlay (Luminosity mode, color image)

Nexus oneNexus 7
SdkNDKSdkNDK
2563120485090
21221004520190
21621104330100

On average, the speed gain for Nexus One is 21 times, for Nexus 7 it is 36 times.
')
Layer overlay (Color Dodge mode, single color)

Nexus oneNexus 7
SdkNDKSdkNDK
2673thirty572080
257220623070
257320611070

On average, the speed gain for the Nexus One is 112 times, for the Nexus 7 it is 82 times.

Layer overlay on transparency gradient

Nexus oneNexus 7
SdkNDKSdkNDK
13013213010470
12213302670620
12113002770610

On average, the speed gain for Nexus One is 4 times, for Nexus 7 - 5 times.

As you can see, the results differ by one or even two orders of magnitude. I deliberately cited figures in absolute values, so that the real acceleration of work from the use of NDK could be seen. The relatively modest results of the last test are due to the fact that the standard functions of the OpenCV library, which are fairly well optimized, were used to calculate the overlay. Accordingly, this test clearly shows the real acceleration of the application as a whole.

Casually touch the use of the library OpenCV. As I expected, the Java part of the library is a regular wrapper over the NDK. Still, I conducted the above experiments on fairly heavy and long-playing algorithms, such as finding characteristic points in images, grabcut method. The difference in speed between Java and NDK was a maximum of 10%, which can be attributed to inaccuracy, since at that moment I could not get completely identical images.

Update. It’s rather unpleasant to admit one’s own mistakes, but what to do.
So, here is a sample code with which I evaluated the performance of the Java implementation of the OpenCV library:
for (int i=0; i<mat.rows(); i++){ for (int j=0; j<mat.cols(); j++) { double[] matPix = mat.get(i, j); double[] topPix = top.get(i, j); if (matPix[0]+topPix[0]>255){ matPix[0] = 255.; } else { matPix[0] = (255. * matPix[0]) / (256. - topPix[0]); } mat.put(i, j, matPix); } } 

We go around pixel by pixel to two matrices of the same size and, depending on the value of the corresponding pixel of the one and the other matrix, we calculate the resulting pixel.
Thanks to the comments in the comments on the article, the code was optimized as follows (monochrome pictures):
 int size = mat.cols(); byte[] matPix = new byte[size]; byte[] topPix = new byte[size]; for (int i=0; i<mat.rows(); i++){ mat.get(i, 0, matPix); top.get(i, 0, topPix); for (int j=0; j<size; j++) { int mp = (matPix[j] & 0xFF); int tp = (topPix[j] & 0xFF); if (mp+tp>255){ mp = 255; } else { mp = (255 * mp) / (256 - tp); } matPix[j] = (byte) mp; } mat.put(i, 0, matPix); } 

For testing, again, I used real Nexus One and Nexus 7 devices, I also sent 3 megapixel pictures to the input and in either case I wanted to compare the performance of the devices with each other. The results (average, in ms) are tabulated:

Nexus oneNexus 7
SdkNDKSdkNDK
No optimization3540424522755160
With optimization340205210120

Conclusions everyone can make himself. Code optimization in C ++ was carried out on the same principle as in Java. I do not cite the code, it is of the same type as above.

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


All Articles