views:

140

answers:

5

I am exploring a solution at my client where we have to call an API that is available in both C# and Java from our C++ application. We would like this to be a cross platform application (PC & Mac), so Java is preferred, but performance is more important. I've been trying to do some research on the performance of C++ calls to C# vs Java but haven't found any solid information. The idea is to use JNI to call the Java API or managed C++ to call the C# API.

Does anyone out there have information or insight as to what would be better performance wise? These calls will potentially be performed heavily, so volume does come into play.

Thanks!

+3  A: 

I cannot offer you a definitive answer, but I have done JNI to C library calls (not the reverse), .NET to wrapped Java library calls, and .NET to .NET library calls. I don't have official numbers on any of them, but the .NET to .NET calls, whether managed C++ or C# were both the easiest and fastest. Because they were both .NET, there was a common set of datatypes supported on both sides. In the other instances, there was lots of ugly marshaling code required to convert between datatypes in different languages. The .NET Framework was designed with the intent that calls between different .NET libraries would be transparent of their original language and it does this very well.

Another consideration is that in a high-volume environment, the performance of the individual libraries may be a bigger concern than the interop performance. In other words, if the Java library is 25% faster than the C# library, it may make sense to use the Java library even if the interop with C# is faster and easier than with Java.

Dan
+1  A: 

I assume the C# and Java API are the same. I used to work in an environment where both C# and Java had to talk to the same C++ library through interop / JNI. It seems the Java version was more consistent when it came to performance, as the API was quite chatty and generated a lot of transient objects.

This is what our calls looked like :

double myDouble= theCPPWrapper.GetField("foo").AsDouble(); 

with theCPPWrapper.GetField(string) returning a JNI Field class and the Field.AsDouble() method going through yet another layer of interop for nothing...

So the GC was full of transient Field objects and somehow Java seemed to cope better.

In the end the fix was to change the JNI / Interop api to look thus :

double myDouble = theCPPWrapper.GetFieldAsDouble("foo"); // no transient Field. Yay!

Whatever you consider, first check that your native API isn't unnecessarily chatty, or your GC will suffer.

Cheers, Florian

Florian Doyon
A: 

If you will manage several and complex calls between all languages I suggest the use of an abstraction layer that separate all calls.

I used CORBA and XML-RPC in same situation with success, both are well supported/documented. But they have pros & cons that you will study before choice one.

Gustavo V
A: 

There are quite a few benchmarks comparing C/C++ and Java. (The second one also includes C#) NOTE: These are just benchmarks and should be taken with a grain of salt.

http://www.idiom.com/~zilla/Computer/javaCbenchmark.html
http://reverseblade.blogspot.com/2009/02/c-versus-c-versus-java-performance.html

Doing everything in one environment is always faster, compared to going through a conversion layer. Of course if you start doing remote calls it will always be a lot slower. The idea is to keep granularity high if you are going to cross-talk.

Romain Hippeau
A: 

What's the plan for calling C# code on the Mac? Or would you use Java on the Mac and C# for Windows? Just curious about the support requirements you're willing to rack up. I would hope that calling managed C++ from unmanaged C++ would be fairly efficient, but I confess I've never done it.

TMN
Its basically either we use the Java API and support both Windows and Mac, or we use C# and support only Windows. The client has a desire to enable Mac support, but performance takes precedence over environment.
wezman