C ++调用Java代码与C#代码的性能

时间:2010-07-13 14:44:20

标签: c# java c++ java-native-interface managed-c++

我正在客户端探索一个解决方案,我们必须从C ++应用程序中调用C#和Java中提供的API。我们希望这是一个跨平台应用程序(PC和Mac),因此Java是首选,但性能更重要。我一直在尝试对C#与Java的C ++调用的性能进行一些研究,但是没有找到任何可靠的信息。我们的想法是使用JNI调用Java API或托管C ++来调用C#API。

有没有人有关于什么会更好的表现明智的信息或见解?这些调用可能会大量执行,因此音量会发挥作用。

谢谢!

6 个答案:

答案 0 :(得分:4)

我无法为您提供明确的答案,但我已经完成了JNI到C库调用(不是相反的),.NET到包装的Java库调用,以及.NET到.NET库调用。我没有关于它们的官方数字,但.NET to .NET调用,无论是托管C ++还是C#都是最简单和最快的。因为它们都是.NET,所以双方都支持一组通用的数据类型。在其他情况下,在不同语言的数据类型之间进行转换需要很多丑陋的编组代码。 .NET Framework的设计旨在使不同.NET库之间的调用对原始语言透明,并且非常好。

另一个考虑因素是,在高容量环境中,各个库的性能可能比互操作性能更重要。换句话说,如果Java库比C#库快25%,即使使用C#的interop比使用Java更快更容易,使用Java库也是有意义的。

答案 1 :(得分:1)

我认为C#和Java API是相同的。我曾经在一个C#和Java都必须通过interop / JNI与同一个C ++库交谈的环境中工作。看起来Java版本在性能方面更加一致,因为API非常繁琐并且生成了大量的瞬态对象。

这就是我们的电话:

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

theCPPWrapper.GetField(string)返回一个JNI Field类,Field.AsDouble()方法通过另一层互操作无效...

因此,GC充满了瞬态的Field对象,而Java似乎更好地应对了。

最后,修复是将JNI / Interop api更改为:

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

无论您考虑什么,首先要检查您的原生API是否不必要,或者您的GC会受到影响。

干杯, 弗洛里安

答案 2 :(得分:0)

如果您要管理所有语言之间的多个复杂调用,我建议使用一个分隔所有调用的抽象层。

我在成功的情况下使用CORBA和XML-RPC,都得到了很好的支持/记录。 但他们有优点和缺点在选择之前你将学习的缺点。

答案 3 :(得分:0)

有很多基准比较C / C ++和Java。 (第二个还包括C#) 注意:这些只是基准,应该用一粒盐。

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

与通过转换层相比,在一个环境中执行所有操作总是更快。当然,如果你开始做远程调用,它总是会慢得多。如果您要进行交谈,我们的想法是保持较高的粒度。

答案 4 :(得分:0)

我没有C#-to-Java的指标。但是,我们在调用C ++到Java方面有很多经验。即使在缓存了所有类和方法ID之后,它也非常慢。 C ++ / JNI调用似乎需要大约1000个时钟周期,我们观察到大约3M次呼叫/秒作为限制。因此,我们经历了多次优化迭代,包括在一次调用中将数据块传输到Java。此外,您必须检查Java异常或至少在返回时重置异常状态,这会增加额外的开销。

另一方面,从Java调用C ++非常快。如果你可以这样做,那就去做吧。有一些涉及“延续”的高级技术,其中Java和C ++反转控制。它是这样的:

C++ -> Java: Start the continuation loop
   Java: while some condition
      Java -> C++: What do you want me to do
      C++: please do this action for me
      Java does the action

这种控制反转不适合许多(大多数?)应用程序,但这是另一个想法。您也可以考虑各种RPC方法,但这些方法也会相当缓慢(1M /秒左右)。

答案 5 :(得分:-1)

在Mac上调用C#代码的计划是什么?或者你会在Mac上使用Java而在Windows上使用C#吗?只是好奇你愿意支持的支持要求。我希望从非托管C ++调用托管C ++会相当有效,但我承认我从未做过。

相关问题