zoukankan      html  css  js  c++  java
  • 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方法:

    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动态链接库,并测试,最后时间为:

    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. }  
    1. JNI消耗的总时间(ms):16  

     

    【JNA实现】

    对于JNA,我们可以直接先写C代码了,如下分别为.h文件和.cpp文件:

    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. }  
    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包,代码为:

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


    测试代码和结果为:

    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. }  
    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对象,我们同样可以将一个值在一次本地方法调用中设置到对象里,然后在下一次调用中使用。当然这个值是保存在本地代码中的。

  • 相关阅读:
    前端学习
    python 镜像
    os模块常用操作
    pandas 缺失值与空值处理
    pandas 根据列的值选取所有行
    pandas模块
    编码与解码
    正则表达式
    pthon之字典的遍历
    python作用域
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/6109694.html
Copyright © 2011-2022 走看看