NDK与JAVA的表现

yar*_*rin 11 c java android android-ndk

是否有任何机构假设使用NDK的C代码与Java代码相同的计算速度有多快?(如果有的话)

假设我在java代码中在Y秒内进行X计算(相同的计算).
通过NDK中的C代码可以在相同的Y秒内完成多少次X计算?
1.2?
2.7?
任何猜测数字?

可以说,计算结果是B = L/A + C/D(所有X计算都是相同的).

编辑:

我为什么这么问?
因为我考虑将我的java处理相机帧移动到C代码.以获得更大的分辨率机会

Uni*_*dow 18

由于没有其他人想要触及这个话题,因为它不认真考虑回答它,我将有一个去:

  • Java编译为字节码,字节码由JIT编译为本机代码.
  • C直接编译为本机代码.

差异实际上是额外的编译步骤,理论上Java应该比C编译器做得更好,这就是原因:

  • Java可以将统计计算插入到生成的本机代码中,然后在一段时间后重新生成它,以针对代码中的当前运行时路径对其进行优化!

最后一点听起来很棒,但java会有一些权衡:

  • 它需要GC运行来清理内存
  • 它可能根本不是JIT代码

GC复制活动对象并抛出所有死对象,因为GC不需要为死亡对象执行任何操作,理论上GC比对象的正常malloc/free循环更快.

然而,大多数Java拥护者都忘记了一件事,那就是没有任何东西说你必须在编码时使用malloc/free每个对象实例.你可以重用内存,你可以动画内存块和释放包含数千个临时内存块的内存块对象一气呵成.

随着Java的大量增加,GC时间增加,增加了停滞时间.在某些软件中,GC清理周期期间的停顿时间完全正常,在其他软件中则会导致致命错误.尝试保持软件在GC发生时在规定的毫秒数内响应,您将看到我在说什么.

在某些极端情况下,JIT也可能根本不选择JIT代码.当JITed方法变大时会发生这种情况,如果我记得正确则会发生8K.非JITed方法的运行时损失在20000%的范围内(至少在我们的客户处是200倍).当JVMs CodeCache开始变满时,JIT也会被转换(如果一次又一次地将新类加载到JVM中,这种情况可能发生,也发生在客户站点).有一次,JIT统计数据还将一台128核机器的并发性降低到基本单核性能.

在Java中,JIT有一段特定的时间将字节码编译为本机代码,将所有CPU资源用于JIT 是不行的,因为它与执行程序实际工作的代码并行运行.在C中,编译器可以运行,只要它需要吐出它认为最优化的代码即可.它对 Java的执行时间没有影响.

我说的是这个:

  • Java为您提供了更多,但并不总是取决于您的表现.
  • C给你的少,但它取决于你如何表现.

所以回答你的问题:

  • 不选择C over Java不会使您的程序更快

如果你只对预分配缓冲区进行简单的数学运算,那么Java和C编译器都应该吐出相同的代码.


Jit*_*yay 7

您可能无法从任何人那里得到明确的答案.这些问题远比它看起来复杂得多.

使用NDK或SDK在OpenGL中输入相同数量的多边形是没有问题的.毕竟它只是相同的OpenGL调用.渲染多边形的时间(批量)将函数调用开销的时间按数量级进行.所以它通常是完全可以忽略的.

但是,只要应用程序变得更复杂并执行一些严肃的计算(AI,场景图管理,剔除,图像处理,数字运算等),本机版本通常会快得多.

另外还有一件事:除了目前没有JIT编译的基本问题.当前的dalvikvm及其编译器似乎非常基础,没有做任何优化 - 甚至不是最基本的!

有这个(非常好的)视频:Google I/O 2009 - 为Android编写实时游戏在我看到之后,我很清楚我肯定会在NDK中使用C++.

例如:他正在谈论函数调用"不要使用函数调用"的开销....所以是的,我们回来了 - 在1970年之前,开始讨论结构化编程的成本以及仅使用全局变量和结果的性能优势.

垃圾收集是游戏的真正问题.所以你会花很多时间思考如何避免它.即使格式化字符串也会创建新对象.所以有一些提示:不要显示FPS!说真的,如果您了解C++,使用new和delete管理内存可能比调整体系结构以减少/避免垃圾收集更容易.

看起来如果你想编写一个非平凡的实时游戏,你就会失去Java的所有优势.不要使用Getters和Setter,不要使用函数调用.避免任何抽象等严重?

但回到你的问题:NDK vs SDK的性能优势可以是0-10000%.这完全取决于.