Performa Android Runtime vs NDK

Saat mengembangkan mesin game untuk Android, saya yakin bahwa kode C / C ++ asli akan dieksekusi lebih cepat daripada kode Java yang serupa. Pernyataan ini benar, tetapi tidak untuk Android versi terbaru. Untuk memeriksa mengapa ini terjadi, saya memutuskan untuk melakukan sedikit riset.





Untuk pengujian, Android Studio 4.1.3 digunakan - untuk Java Android SDK (API 30), untuk C / C ++ Android NDK (r21, compiler CLang). Tes ini cukup bodoh karena melakukan operasi aritmatika pada larik int dalam dua loop bersarang. Tidak ada yang bermakna dan spesifik.





Berikut adalah metode yang ditulis dalam Java:





public void calculateJava(int size) {
    int[] array = new int[size];
    int sum = 0;

    for (int i=0; i<size; i++) {
        array[i] = i;
        for (int j=0; j<size; j++) {
            sum += array[i] * array[j];
            sum -= sum / 3;
       }
    }    
 }
      
      



C/C++ ( Java GC):





extern "C" JNIEXPORT void JNICALL Java_com_axiom_firstnative_MainActivity_calculateNative(
        JNIEnv* env,
        jobject,
        jint size) {

    int* array = new int[size];
    int sum = 0;

    for (int i=0; i<size; i++) {
        array[i] = i;
        for (int j=0; j<size; j++) {
            sum += array[i] * array[j];
            sum -= sum / 3;
        }
    }

    // delete[] array;
}

      
      



, Java:





     long startTime = System.nanoTime();
     calculateNative(4096);
     long nativeTime = System.nanoTime() - startTime;
                
     startTime = System.nanoTime();
     calculateJava(4096);
     long javaTime = System.nanoTime() - startTime;
                
     String report = "VM:" + System.getProperty("java.vm.version")
                        + "\n\nC/C++: " + nativeTime 
                        + "ns\nJava: " + javaTime + "ns\n"
                        + "\nJava to C/C++ ratio " 
                        + ((double) javaTime / (double) nativeTime);
      
      



Samsung Galaxy Tab E (Android 4.4.4) :

Java time: 2 166 748 ns

C/C++ time: 396 729 ns (C/C++ 5 )





Prestigio K3 Muze (Android 8.1):

Java time: 3 477 001ns ( )

C/C++ time: 547 692ns (C/C++ 6 ),

Java 30-40% (?).





Samsung Galaxy S21 Ultra (Android 11):

Java time: 111 000ns

C/C++ time: 121 269ns

: Java 9% 40-50% C/C++ .





CLang (-O3)  C/C++ ~30-35% (Prestigio K3 Muze Android 8.1) Java , .





Smasung Galaxy S21 Ultra (Android 11) Java 10-20% /C++ CLang (-O3). ...





p.s. , , CPU.





, Java Android C/C++ ? ?

. Android Runtime Ahead-of-Time Java , Just-In-Time . . :





The JIT compiler complements ART's current ahead-of-time (AOT) compiler and improves runtime performance. Although JIT and AOT use the same compiler with a similar set of optimizations, the generated code might not be identical. JIT makes use of runtime type information can do better inlining and makes on stack replacement (OSR) compilation possible, all of which generate slightly different code.





Java NDK C/C++ ?

Menurut saya, untuk perangkat lama dengan mesin virtual Dalvik VM (hingga Android 7.0) - pasti ya. Sedangkan untuk perangkat yang lebih baru, dengan versi Android yang lebih tinggi dari 7.0 (di mana runtime ART digunakan), ini tidak masuk akal, kecuali Anda adalah pengembang C / C ++ berpengalaman yang sangat memahami cara kerja CPU dan mampu membuatnya. pengoptimalan lebih baik daripada Android Runtime. Dan permainan tidak sebanding dengan candle (efek / usaha), kecuali untuk kasus-kasus berikut:





  • Anda mem-porting aplikasi C / C ++ yang ada ke Android





  • Anda ingin menggunakan pustaka C / C ++ yang tidak tersedia dari Java





  • Anda ingin menggunakan API yang tidak tersedia di Android SDK





PS Jika Anda memiliki pemikiran, saya akan dengan senang hati berkomentar.








All Articles