Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've tried rewriting some Java functions in C++ and called them using JNI. I observed that it takes longer time to execute the native C++ functions as compared to Java functions, due to the JNI overhead.

As it is widely believed that C++ has certain advantages over Java, I wanted to know whether rewriting some Java code to C++, with a view to improve overall performance of the Java application, a good idea?

If yes, then what parts of the application should be rewritten and how can a Java application use it?

share|improve this question

closed as too broad by gnat, GlenH7, Yusubov, MichaelT, Michael Kohne Sep 3 '13 at 18:47

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs. If this question can be reworded to fit the rules in the help center, please edit the question.

This has come over and over again and the answer keeps being that no. But if you have a huge bunch of C/C++ code, then it's a smart way of putting it to werk. –  uprego Sep 3 '13 at 6:47
Also do you like rewriting werking code? –  uprego Sep 3 '13 at 6:51
If it can improve speed significantly and save some memory, then yes. otherwise no. –  Sorter Sep 3 '13 at 6:58
@D3EP4K: if "data intensive" means you have to read or write lots of data from/to an external storage, then the bottleneck is often the I/O limit of your storage system (which is independent of Java or C++). But it depends a whole lot of what you are doing with this data in your program, in special cases a C++ routine could be faster, if implemented well (or slower, if implemented not so well or JNI becomes a bottleneck). Performance optimization is almost always case specific, you expect to find "general answers" where there are only specific ones. –  Doc Brown Sep 3 '13 at 11:34
This is a good question. REOPEN! –  Thomas Eding Sep 4 '13 at 0:18

2 Answers 2

up vote 10 down vote accepted

I would advise against it; in the latest releases JVM was improved very much and the performance differences are minimal, for typical production code. Moreover JNI itself is not free from the performance POV and overall you would lose performance rather than achieve more (as you have found out in your case). In addition to this, native code is not safe (you may have corrupt memory), are less portable and harder to debug.

Try to improve performance by classical techniques (better algorithms and data structures, optimization, reduced I/O overhead etc.) and Java techniques (JVM tuning). Only if you have legacy APIs in native code or you need to perform large computation extensive tasks is JNI recommended.

See also Item 54: Use native methods judiciously in Joshua Bloch's Effective Java (2nd edition) for a more advised reference.

share|improve this answer
There is work starting on providing a proper FFI for the JVM, but completely agree, going JNI/native rarely gives you a speed boost. –  Martijn Verburg Sep 3 '13 at 7:20
I worked on a project that ported a C++ library to Android using the NDK and JNI. It was one of those "seemed like a good idea at the time" things. We thought that we'd get both portability and performance. We ended up getting very little of the former and none of the latter. If we had it to do over, we'd have just rewritten it in Java. (Speaking as a C++ bigot who hates Java.) –  Steven Burnap Sep 3 '13 at 15:54

I've used JNI now and then both in standard Java (desktop) applications and Android applications. Here's the gist of it all:

1 . Your question asks specifically if performance is improved by JNI: mostly, no. There are some very few and specific situations where performance is improved. 98.3% of the time this will not be the case. Also, adding JNI solely for performance benefits will greatly complicate your project (as compared to just writing it in Java or C/C++): There are a huge lot of very good tools (IDE, project management tools, libraries, testing tools etc) for Java-only projects (as they are for C and/or C++ -only projects). However there are a lot less (and, IMHO, of lesser quality) such tools that allow to deal with a mixed (Java) + (JNI) +(C and/or C++) project all in one go. More often than not you'll need to bring in separate tools for the Java part of your project, another for the C/C++ part of your project and maybe do a bit of custom tools developement (like scripts and such) for your JNI parts.

Here's an example: I've recently helped a friend with a Java project that had about 90% of its code use the BigDecimal and BigInteger classes. The code did a lot of the common (and some of the more exotic) algebraic operations with these: +-/* but also log, square roots and some I can't remember now. We also tried replacing those parts of the code with JNI and C code that used the MPFR library, after noticing that the features we were using out of Java's BigXXX API were also present in this library. Long story short, in this particular case, the performance gain was of about 10-15 times. Finally we decided to implement the whole module in C and only use Java for the UI along with non-granular JNI calls towards the new C module.

2 . I think the biggest reason why someone would use JNI is if he/she already has a lot of complex C and/or C++ code which needs to be integrated with Java code. One place where this may apply is when porting an existing video game to the Android platform: Most games are made in C/C++. Android, while at it's core runs on a Linux kernel and deals with C/C++ code, offers in fact a Java API (a Java development environment very similar to the JDK/JVM you get on your PC/Mac). In such a context, doing a thin Java wrapper around existing C++ code in orderto get an old game up and running on Android is a lot faster than converting all the C/C++ code to Java entirely. With the Java thin wrapper approache there is a loss of performance, but it may very well be negligeable, depending on the resource demands of the original game, etc.

Here's a quote from Android's documentation on this:

Before downloading the NDK, you should understand that the NDK will not benefit most apps. As a developer, you need to balance its benefits against its drawbacks. Notably, using native code on Android generally does not result in a noticable performance improvement, but it always increases your app complexity. In general, you should only use the NDK if it is essential to your app—never because you simply prefer to program in C/C++.

(Bad) Example (which illustrates the last point): I've implemented the A* pathfinding algorithim in Java. I've also made a small, simple graphical demonstration of it as an Android application. I then implemented that same algorithm in C. When running separate benchmarks of the Java and C code, C was sometimes 2-3 times faster (especially if there were a lot of GC when running the Java code). So I modified my all-Java Android app to make it use the C code via JNI. While the project got a whole lot more complicated (even when using the excellent Sequoyah Eclipse plugin) the actual performance gain was now more like 10-20%, no where near the 200-300% I was seeing when running the Java and C version of this particular code separately.

How ever (and here I quote from memory) one of the earlier Android books (from the Android version 2 era) gave an advanced example of taking the Quake C++ source code and using JNI to make it into an Android App in like 20 pages (about 2-3 hours of work). If the Quake C++ code was all translated to Java (hundreds of thousants of lines of code) instead, it would take a lot longer than that. And since even the Android devices of that time were able to "hide" the performance penalities that came with JNI calling the Quake game, it made for a good trade-off to use JNI here.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.