NDK 与 JAVA 性能对比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20041347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:36:40  来源:igfitidea点击:

NDK vs JAVA performance

javaandroidcandroid-ndk

提问by yarin

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

是否有人假设 C 代码与 NDK 的计算速度与 Java 代码相同?(如果有)

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?

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

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

假设计算是 B=L/A +C/D(所有 X 计算都相同)。

EDIT:

编辑:

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

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

回答by Jitesh Upadhyay

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.

无论是使用 NDK 还是 SDK,在 OpenGL 中放置相同数量的多边形都没有问题。毕竟它只是相同的 OpenGL 调用。渲染多边形的时间(批量)超过了函数调用开销的时间数量级。所以它通常是完全可以忽略的。

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.

但是一旦应用程序变得更加复杂并执行一些重要的计算(AI、场景图管理、剔除、图像处理、数字运算等),原生版本通常会快得多。

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!

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

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.

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

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.

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

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.

垃圾收集对于游戏来说是一个真正的问题。因此,您将花费大量时间思考如何避免它。即使格式化字符串也会创建新对象。所以有一些提示,比如:不要显示 FPS!说真的,如果您了解 C++,那么使用 new 和 delete 管理内存可能比调整架构以减少/避免垃圾收集更容易。

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?

似乎如果你想编写一个非平凡的实时游戏,你就失去了 Java 的所有优势。不要使用 Getter 和 Setter,不要使用函数调用。避免任何抽象等。认真地?

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

但回到你的问题:NDK 与 SDK 的性能优势可以是 0-10000%。这一切都取决于。

回答by UnixShadow

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.
  • Java 编译为字节码,字节码由 JIT 编译为本机代码。
  • C 直接编译为本机代码。

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应该比你的C编译器做得更好,原因如下:

  • Java can insert statistics calculations into the generated native code, and then after a while regenerate itto optimize it against the current runtime paths in your code!
  • Java 可以将统计计算插入生成的本机代码中,然后过一段时间重新生成它以针对代码中的当前运行时路径对其进行优化!

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

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

  • It needs GC runs to clean out memory
  • It may not JIT code at all
  • 它需要运行 GC 来清理内存
  • 它可能根本就不是 JIT 代码

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.

GC 复制活着的对象并抛出所有的死对象,因为 GC 不需要为死对象做任何事情,只需要为活着的对象做任何事情,理论上 GC 比对象的正常 malloc/free 循环更快。

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.

然而,大多数 Java 拥护者忘记了一件事情,那就是没有说在编码 C 时你必须 malloc/free 每个对象实例。你可以重用内存,你可以 malloc up 内存块和释放包含数千个临时内存块一次性对象。

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.

对于 Java 上的大堆,GC 时间会增加,从而增加停顿时间。在某些软件中,GC 清理周期中的停顿时间是完全可以的,而在其他软件中,它会导致致命错误。尝试让您的软件在 GC 发生时在规定的毫秒数内做出响应,您就会明白我在说什么。

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.

在某些极端情况下,JIT 也可能选择根本不 JIT 代码。如果我没记错的话,当 JITed 方法很大时会发生这种情况,即 8K。非 JITed 方法的运行时间损失在 20000% 范围内(慢 200 倍,至少在我们的客户中是这样)。当 JVM 的 CodeCache 开始变满时,JIT 也会被关闭(如果不断将新类不断加载到 JVM 中,这可能会发生,也会发生在客户站点)。在某一时刻,JIT 统计数据还将一台 128 核机器上的并发性降低到基本单核性能。

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 resourcesfor 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.

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

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.
  • Java 为您提供了更多,但它的执行方式并不总是取决于您。
  • C 给你的更少,但它的表现取决于你。

So to answer your question:

所以要回答你的问题:

  • No selecting C over Java will not make your program faster
  • 不选择 C ​​而不是 Java 不会使您的程序更快

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

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