JNI與JNA性能比較


JNI與JNA性能比較

 

在介紹JNA時,提到了JNA是基於JNI的,是在JNI上封裝了一層,JNI性能不如JNA。最近在網上看到篇簡單的比較這兩者性能的文檔,感覺不錯,現轉載一下:

分別用JNI和JNA的方式建立dll,dll中包含一個get方法和一個set方法,在Java端進行循環調用1000*1000次,比較所耗費的時間。

JNI和JNA調用的不是同一個dll,但是功能和代碼基本相同。本測試從一定角度反映他們的性能。

【JNI實現】

先編寫Java相關的native方法:

[java] view plain copy
  1. package crayon.jni;  
  2.   
  3. public class JNITest {  
  4.     public native static void set(int i);  
  5.     public native static int get();  
  6.     static{  
  7.         System.loadLibrary("JNITest");  
  8.     }  
  9.       
  10. }  

然后利用javah命令從上述帶native方法的class文件導出.h頭文件,並編寫C代碼實現為:

  1. #include "stdafx.h"  
  2. #include "JNITest.h"  
  3.   
  4. long tmp = 0;  
  5.   
  6. JNIEXPORT void JNICALL Java_crayon_jni_JNITest_set  
  7.     (JNIEnv *, jclass, jint value){  
  8.         tmp = value;  
  9. }  
  10.   
  11. JNIEXPORT jint JNICALL Java_crayon_jni_JNITest_get  
  12.     (JNIEnv *, jclass){  
  13.         return tmp;  
  14. }  


生成dll動態鏈接庫,並測試,最后時間為:

[java] view plain copy
  1. package crayon.jni;  
  2.   
  3. public class TestJNI {  
  4.     public static void main(String[] args) {  
  5.         long beginTime = System.currentTimeMillis();  
  6.         int i;int j;  
  7.         for(i=0;i<1000;i++){  
  8.             for(j=0;j<1000;j++){  
  9.                 JNITest.set(i*j);  
  10.                 JNITest.get();  
  11.             }  
  12.         }  
  13.         long totalTime = System.currentTimeMillis()-beginTime;  
  14.         System.out.println("JNI消耗的總時間(ms):"+totalTime);  
  15.     }  
  16.   
  17. }  
[html] view plain copy
  1. JNI消耗的總時間(ms):16  

 

【JNA實現】

對於JNA,我們可以直接先寫C代碼了,如下分別為.h文件和.cpp文件:

[html] view plain copy
  1. #ifdef JNATEST_EXPORTS  
  2. #define JNATEST_API __declspec(dllexport)  
  3. #else  
  4. #define JNATEST_API __declspec(dllimport)  
  5. #endif  
  6.   
  7. extern "C" {  
  8.     JNATEST_API void set(long l);  
  9.     JNATEST_API long get();  
  10. }  

 

[html] view plain copy
  1. #include "stdafx.h"  
  2. #include "JNATest.h"  
  3.   
  4. long tmp;  
  5. JNATEST_API void set(long l){  
  6.     tmp = l;  
  7. }  
  8. JNATEST_API long get(){  
  9.     return tmp;  
  10. }  

直接寫Java端代碼調用上述導出的dll文件,注意別忘記引入JNA相關的jar包,代碼為:

[html] view plain copy
  1. package crayon.jna;  
  2.   
  3. import com.sun.jna.Library;  
  4. import com.sun.jna.Native;  
  5.   
  6. public interface JNATest extends Library {  
  7.     JNATest INSTANCE = (JNATest) Native.loadLibrary(  
  8.                 "D:/CC/Tools_Tool_ITT_StdPrj_Dev/PF_Tools_VOB/Tools_SubTool/src/JNATest/Release/JNATest", JNATest.class);  
  9.     public void set(int i);  
  10.     public int get();  
  11.   
  12. }  


測試代碼和結果為:

[html] view plain copy
  1. package crayon.jna;  
  2.   
  3. import com.sun.jna.Library;  
  4. import com.sun.jna.Native;  
  5.   
  6. public interface JNATest extends Library {  
  7.     JNATest INSTANCE = (JNATest) Native.loadLibrary(  
  8.                 "D:/CC/Tools_Tool_ITT_StdPrj_Dev/PF_Tools_VOB/Tools_SubTool/src/JNATest/Release/JNATest", JNATest.class);  
  9.     public void set(int i);  
  10.     public int get();  
  11. }  
[html] view plain copy
  1. JNA消耗的總時間(ms):2593  

 

綜上比較:JNI 16ms  << JNA 2593ms!!!性能差距還蠻大的!!

 

本着赤果果地實事求是地態度,我在自己的lenovo 昭陽K46(XP,處理器i3,內存升級4G--實際使用3G)的機器上測試了一下,結果為(取10次平均):JNI 120.5ms   JNA 4535.8ms !!我的本本貌似不是很給力,但測試結果整體趨勢差不多!

 

這次試驗,本身也有一個收獲,就是:在JNI(或JNA)應用中,在Java端,我們會有一個對象,其中調用的方法都會映射到本地代碼中,只要我們是同一個Java對象,我們同樣可以將一個值在一次本地方法調用中設置到對象里,然后在下一次調用中使用。當然這個值是保存在本地代碼中的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM