2017-09-28 4 views
3

Javaコードの一部をC++に移植して、Androidでの計算を高速化しました(これは物理サブルーチンでした)。私が見つけたのは、ネイティブコードがJavaコードよりも数倍遅く動作することでした。私はおそらく、私のプロジェクトの設定に問題があったか、または配列処理をしていると思われました。HelloAndroidJniプロジェクトに単純なループを入れて、速度差をテストして、同様の結果を得ました。ネイティブのC++コードがAndroid上のJavaよりも遅く動作するのはなぜですか?

Javaコード: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); 
} 

ループ:

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 ms、Java = 195 msです。ネイティブコードをJavaよりも遅く実行させる原因は何でしょうか?

EDIT:ちなみに、ネイティブコードはエミュレータ上のJavaよりもはるかに高速実行されますが、自分の携帯電話(LG V20 /キンギョソウ820)上のネイティブがはるかに遅いです。

+2

コンパイラの最適化を有効にしましたか? – kmkim85

+0

いいえ、それは私が思った最初のことでしたが、Googleが検索するコンパイラのフラグは何も示唆していませんでした。現在私はフラグを使用していません。どのフラグを使用する必要がありますか? – HypnoToad

+0

JNI呼び出しのオーバーヘッドのため はhttps://stackoverflow.com/questions/13973035/what-is-the-quantitative-overhead-of-making-a-jni-call –

答えて

2

フライ最適化上のJavaは、あなたのループがネイティブのように高速で行うことができます。一方、APP_OPTIM=releaseを使用しないと、C++コンパイラは最適化されていないデバッグ・コードを生成します。

持ち帰りは規律の方法で符号化された場合、Javaでクランチング実際数は、非常に効率的であり得るということです。しかし結局のところ、Cで同じコードを効率的にコーディングするには規律が必要です。

+0

ありがとう、これはまさに問題でした。私はデバッグビルドがネイティブコードをJavaコードよりも遅くするのを期待していませんでした! – HypnoToad

関連する問題