【问题标题】:Why is my native C++ code running so much slower than Java on Android?为什么我的原生 C++ 代码在 Android 上的运行速度比 Java 慢得多?
【发布时间】:2017-09-28 01:08:52
【问题描述】:

我将部分 Java 代码移植到 C++ 以加快 Android 上的计算(这是一个物理子程序)。我发现本机代码的运行速度比 Java 代码慢几倍。我想可能是我的项目配置有问题,或者可能是数组处理有问题,所以我在 HelloAndroidJni 项目中放置了一个简单的循环来测试原始速度差异,并得到了类似的结果。

Java 代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    /* ...generic boilerplate code... */

    TextView tv = (TextView) findViewById(R.id.sample_text);
    int loopCount = 100000;

    //time the native method
    long ticks = System.nanoTime();
    int result = nativeTest(100000);
    long nativeTime = (System.nanoTime() - ticks) / 100000;

    //time the Java method
    ticks = System.nanoTime();
    result = javaTest(100000);
    long javaTime = (System.nanoTime() - ticks) / 100000;

    //present results
    tv.setText("Native=" + nativeTime + "; Java=" + javaTime);
}

Java 中的循环:

int javaTest(int count) {
    int result = 0;
    for (int i = 0; i < count; i++) {
        for (int j = 0; j < 100; j++) {
        result += 34432; result++;
        result -= 34431; result--;
    } }
    return result;
}

还有 C++ 代码:

JNIEXPORT jint JNICALL
Java_com_fringecode_helloandroidjni_MainActivity_nativeTest(
        JNIEnv *env, jobject jThis, jint count) {
    int result = 0;
    for (int i = 0; i < count; i++) {
        for (int j = 0; j < 100; j++) {
            result += 34432; result++;
            result -= 34431; result--;
        } }
    return result;
}

项目的其余部分与 HelloAndroidJni 示例项目相同。典型运行的结果是 Native=2580 毫秒,Java=195 毫秒。是什么让原生代码的运行速度比 Java 慢很多?

编辑:顺便说一句,本机代码在模拟器上的运行速度比 Java 快得多,但在我的手机(LG V20 / Snapdragon 820)上,本机代码要慢得多。

【问题讨论】:

  • 您是否启用了任何编译器优化?
  • 不,这是我想到的第一件事,但搜索 Google 并没有建议我应该使用任何编译器标志。目前我没有使用任何标志。我应该使用哪些标志?
  • 因为 JNI 调用开销。见这里*.com/questions/13973035/…
  • 可能还是优化了,在return语句中尝试concact结果再测试。而且@DenisDda,JNI 调用开销小于 1 毫秒,所以这应该不是问题。
  • 你应该正确地对其进行微基准测试,循环可能会被优化而不再存在。

标签: java android c++ performance android-ndk


【解决方案1】:

Java 动态优化可以使您的循环与本机一样快。另一方面,如果没有APP_OPTIM=release,C++ 编译器将生成调试未优化的代码。

要点是,如果以规范的方式编码,Java 中的数字运算实际上可能非常有效。但毕竟,在 C 中高效地编码同样需要纪律。

【讨论】:

  • 谢谢,这正是问题所在。我没想到调试版本比 Java 代码更能降低原生代码的速度!
最近更新 更多