Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NDK vs JAVA performance [closed]

Is any body have a assumption how fast will be C code with NDK with the same calculations then java code?(if any)

lets say I am doing X calculations(the same calculations) in Y seconds in java code.
How many X calculations can i do in the same Y seconds through the C code in NDK?
1.2 ?
2.7 ?
any guess number?

Lets say that the calc is B=L/A +C/D (the same one for all X calculations).

EDIT:

Why i am asking this?
because i consider to move my java processing camera frames to the C code.for bigger resolutions opportunities

like image 987
yarin Avatar asked Nov 18 '13 06:11

yarin


2 Answers

You will probably not get a clear anwser from anyone. The questions is far more complex than it looks like.

It is no problem to put the same number of polys out in OpenGL be it with the NDK or SDK. After all it's just same OpenGL calls. The time to render the polys (in a batch) exeeds the time of the function call overhead by orders of magnitude. So it is usually completely neglectable.

But as soon as an application gets more complex and performs some serious calculations(AI, Scene Graph Management, Culling, Image processing, Number crunching, etc.) the native version will usually be much faster.

And there is another thing: Beside the fundamental problem that there currently is no JIT Compilation. The current dalvikvm with its compiler seems to be very basic, without doing any optimizations - even not the most basic ones!

There is this (very good) video: Google I/O 2009 - Writing Real-Time Games for Android After I have seen it, it was clear for me I will definitely use C++ with the NDK.

For example: He is talking about the overhead of function calls "Don't use function calls". ... So yeah we are back - before 1970 and start talking about the cost of structured programming and the performance advantage of using only global vars and gotos.

The garbage collection is a real problem for games. So you will spend a lot of your time thinking how you can avoid it. Even formatting a string will create new objects. So there are tips like: don't show the FPS! Seriously, if you know C++ it is probably easier to manage you memory with new and delete than to tweak your architecture to reduce/avoid garbage collections.

It seems like if you want to program a non trivial real time game, you are loosing all the advantages of Java. Don't use Getters and Setters, Don't use function calls. Avoid any Abstraction, etc. SERIOUSLY?

But back to your question: The performance advantage of NDK vs SDK can be anything from 0-10000%. It all depends.

like image 24
Jitesh Upadhyay Avatar answered Oct 03 '22 23:10

Jitesh Upadhyay


Since no one else want to touch this topic, since its not consider serious to try to answer it, I will have a go:

  • Java compiles to bytecode, and the bytecode compiles to native code by the JIT.
  • C compiles directly to native code.

The difference are really the extra compile step, and in theory java should do a better work then your C compiler, and here's why:

  • Java can insert statistics calculations into the generated native code, and then after a while regenerate it to optimize it against the current runtime paths in your code!

That last point sounds awesome, java do however come with some tradeoffs:

  • It needs GC runs to clean out memory
  • It may not JIT code at all

GC copies alive objects and throws all dead one, since GC does not need to do anything for the dead one only for the live ones, GC in theory is faster then the normal malloc/free loop for objects.

However, one thing is forgotten by most Java advocates and that is that nothing says that you will have to malloc/free every object instance when coding C. You can reuse memory, you can malloc up memory blocks and free memory blocks containing thousands of temporarily objects on one go.

With big heaps on Java, GC time increases, adding stall time. In some software it is totally OK with stall times during GC cleanup cycle, in others it causes fatal errors. Try keeping your software to respond under a defined number of milliseconds when a GC happens, and you will see what I'm talking about.

In some extreme cases, the JIT may also choose not to JIT the code at all. This happens when a JITed method would be to big, 8K if I remember correct. A non JITed method has a runtime penalty in the range of 20000% (200 times slower that is, at least at our customer it was). JIT is also turned of when the JVMs CodeCache starts to get full (if keep loading new classes into the JVM over and over again this can happen, also happen at customer site). At one point JIT statistics also reduced concurrency on one 128 core machine to basically single core performance.

In Java the JIT has a specific amount of time to compile the bytecode to native code, it is not OK to spend all CPU resources for the JIT, since it runs in parallel with the code doing the actually work of your program. In C the compiler can run as long as it needs to spit out what it thinks is the most optimized code it can. It has no impact on execution time, where in Java it has.

What I'm saying is really this:

  • Java gives you more, but it's not always up to you how it performs.
  • C gives you less, but it's up to you how it performs.

So to answer your question:

  • No selecting C over Java will not make your program faster

If you only keep to simple math over a preallocate buffer, both Java and C compilers should spit out about the same code.

like image 119
UnixShadow Avatar answered Oct 03 '22 23:10

UnixShadow