Java is the official programming language of Android and Java is used not only on mobile but also on desktops and servers. Java is quite a unique programming language, especially when compared to other programming languages like C.
There are some big differences that are easy to spot. C is procedure-oriented language and Java is object orientated so forth. However, there are some key differences that affect the performance of programs written in C and Java.
First of all Java programs are not compiled to machine code, They are compiled to an intermediate code called bytecode. This Java bytecode is then executed on a Java Virtual Machine.
So to fulfill the goal of write once run anywhere, a Java Virtual Machine can be implemented on Linux, windows, servers or Android. Therefore the same bytecode or intermediate code can be run on that platform without needing to be recompiled.
However, that means when the program runs, it has to run through itself another program. This virtual machine which of course uses CPU time and memory. Therefore that has an impact on performance.
The other big difference is that Java uses automated memory management. It means that if a program allocates some memory or an object, the program doesn’t need to worry about when that object is no longer needed.
All the garbage collector will run periodically and collect up all the bits of memory that are no longer needed and discard them. The problem is the garbage collector is an expensive thing to run.
For example, if you’re writing a game and you need to update the frames every 16 milliseconds having the garbage collector run right at the time when you’re trying to update the frame, will affect the performance of your app.
C is quite different and it compiled directly down to machine code. If it’s running on a desktop PC running an Intel chip, it will compile directly to the Intel machine code.
If it’s running on an ARM chip on a smartphone, it will compile directly down to the machine code for the ARM chip and it doesn’t have automated memory management.
If the program allocates memory, It is up to the programmer to free that memory at a time at the programmer field is the best. Therefore, generally considered that Java is slightly slower than C when the two are run side by side.
I thought it would be interesting to see how about speed comparison looks on Android. What is the speed difference between C program and a Java program?
Now normally, Java programs are written using the SDK (Software Development Kit) and Google also release a thing called the NDK (Native Development Kit) which allows you to write C and C++ programs for Android.
I’ve written an app that uses both Java code and C code and implements the same functionality in both languages with an attempt to see how much longer, it takes in one language compared to the other.
Now the app does 3 things.
Test 1: It calculates the sha1 hash of a block of data (SHA1(40,000 ITERATIONS))
Test 2: It calculates the first 50 thousand prime numbers using trial by division
Test 3: Finally, it runs a mathematical function that I wrote and it runs that 50 thousand times to see how long it takes.
Now there are a couple of things I want to mention before, we look at the actual results. First one is about optimization. Every software engineer knows that software should be optimized to run faster on each platform that it’s being deployed to.
Now, While I was writing this code because I was looking at how many nanoseconds it took to run each particular function because that was the idea of the benchmark.
I was quite surprised how drastically, I could change the results by implementing a function one way or another. Now I’ve tried my best optimized the Java code and the C code.
It’s also worth mentioning the Android Java virtual machines. Including Android 4.4 KitKat android used a java virtual machine code-named dalvik. It was basically a Java virtual machine that interpreted the bytecode and ran the appropriate instruction on the processor.
It had a thing called just-in-time compiling which means that some sections of the code would be pre-compiled into the native machine code and called upon where needed and that did give a boost to the performance of a virtual machine.
However, from Android 5.0 the default virtual machine became an art to the Android runtime.
Now the Android runtime used ahead of time compiling which means when a program was installed, it was compiled at that moment in the background on to the processor for the processor of your particular machine. (probably an ARM processor though)
Then with the advent of Android 6.0, what happened is that arm had been working in the background with Google to improve that compiling stage in that ahead of time compiler.
So that the machine code was generated and it was even more efficient. That was known as the optimizing compiler. We’ll see the results, how those three different Java virtual machines affect the performance of the Java programs running on phones?
I’d also like to point out they run this benchmark on both 32-bit and 64-bit processors and that’s important is because a lot of the code that’s in my test app uses long integers.
Now traditionally, In C and Java, an integer whole number is 32 bits wide. However, there are things called long integers which are 64 bits wide.
Now of course, if you’re running a Java virtual machine on a 32-bit processor but you have a 64-bit number. It has to do twice the work to process that number.
Actually, it turns out that doing division or specifically the modulus operator for working out the remainder in Java on a 64-bit number is actually quite slow when running on a 32-bit machine.
We’ll see that again reflected in the code.
So what I did was I wrote this app and it runs these 3 tests in Java and in C. Reports the relative difference in the time. But I’ve run this test over 21 different devices. Some are 32-bit, 64-bit, some have KitKat, marshmallow, and lollipop.
Basically what I’m interested in is the difference in the speed between Java and C. I’m not interested in the absolute time.
Yeah! A modern-day snapdragon 820 processor is to be faster than a quad-core 32-bit processor from two years ago but on the same processor, the Java and the C are both running.
The difference between those performances is interesting to us and not the absolute speed. Once I ran the tests, what I actually found was that the result grouped together quite nicely. That 32-bit lollipop and all the results were grouped into one area.
64-bit marshmallow those results were all grouped together. So let’s have a look at what I found out. So the first test was to take a block of data and create a hash and sha-1 hash for that block of data.
Here are the results. Now again this is the relative difference,
The percentage difference between Java and C and the first thing we see is that Java is slower. Now in the worst case scenario which is on an Android 5 32 bit device. It was 300% slow which is four times slower.
Now as we go down through the different devices, we find that 64 bit Android 5, 32 bit Android 4.4 and so on. But the fastest of all of these were Android 6.0 running on a 64-bit processor.
So for a real-world application like creating cryptographic hashes, we find that Java is actually 60% slower than C on the most modern 64-bit processors.
In fact, up to 4 times slower compared to C on older devices. Now the next test works out the first million primes by using trial by division. Now as I pointed out earlier, I’m using 64-bit integers for this and 64-bit division on a 32-bit Java program is actually quite slow.
See that now in the results and the results here are quite amazing if we look at 32-bit Android marshmallow, we see that Java is 265% slower than C.
We also find that 32-bit Android 5 and 32-bit Android 4.4 are significantly slow 172% and 240% respectively. However, once we move over 64bit because we’re using those 64-bit integers, we find Android 5.0 on a 64-bit process was only 40% slower.
Look at this Android 6.0 on a 64-bit processor is only 3% slower. Now that 3% difference is really quite amazing and that’s a lot to do with the new Android runtime with ease ahead of time compiling and the optimizing compiler that went into Android 6.0 marshmallow.
Now my third test runs a mathematical function that I invented it’s my own invention just as some multiplications, division, integer, floating-point and it comes up with a result at the end.
That’s run a million times to see how fast it runs on Java and C. Now again like the prime number testing here, I’m using 64-bit integers.
We can see the difference with a Java virtual machine running 32-bit and 64-bit integers. So looking at the worst results first, here we find that Android 4.4 on a 32-bit machine is 387% slower.
Android 5.0 on a 32-bit machine is 260% slower and Android 6.0 on a 32-bit machine is in 195% slower. Now once again, we move over to 64 bits, we find that Android 5.0 on 64 bits is only 52 percent slower.
But here’s the amazing thing, Java running on an Android 6.0 machine on a 64-bit processor was actually faster than the C code. Now there could be a couple of reasons for this, one is definitely the optimizing compiler. Maybe it found a better optimization than the C compiler did.
Therefore it was able to create faster code and then when you run that a million times, the difference is seen quite clearly. Another thing cause to remember is that what now using this simple mathematical function, the garbage collector doesn’t run at all.
It doesn’t need to run because it’s just doing the math and isn’t much memory allocation going on. So what does all this mean, all the choice between Android and C actually isn’t that black and white.
Because when you’re writing an Android app, you actually want to have access to the Android UI to the Android API, to the various Android services including Google Play and all of those are only available via Java.
C is really only useful if you want to write a game engine or you’ve got some real heavy lifting to do and it will be quicker to do that in C.
Now previously if you had that heavy lifting to do, it might have been worthwhile porting sections of your code to C to get the performance gain.
However, Quick testing has shown is that the performance gap is reducing rapidly and in some cases, it looks now that Java is just as fast as or even faster than C.
- Flutter 1.2 and newly introduced google’s toolkit
- Why iPhones are not selling as expected?
- React Native vs Flutter (2019)
- Best iPhone Reviews in 2019
- What are flutter and dart?