JNI与JNA性能比较

在介绍JNA时,提到了JNA是基于JNI的,是在JNI上封装了一层,JNI性能不如JNA。最近在网上看到篇简单的比较这两者性能的文档,感觉不错,现转载一下:

分别用JNIJNA的方式建立dlldll中包含一个get方法和一个set方法,在java端进行循环调用1000*1000次,比较所耗费的时间。

JNIJNA调用的不是同一个dll,但是功能和代码基本相同。本测试从一定角度反映他们的性能。

【JNI实现】

先编写Java相关的native方法:

package crayon.jni;

public class JNITest {
	public native static void set(int i);
	public native static int get();
	static{
		System.loadLibrary("JNITest");
	}
	
}

然后利用javah命令从上述带native方法的class文件导出.h头文件,并编写C代码实现为:

#include "stdafx.h"
#include "JNITest.h"

long tmp = 0;

JNIEXPORT void JNICALL Java_crayon_jni_JNITest_set
	(JNIEnv *, jclass, jint value){
		tmp = value;
}

JNIEXPORT jint JNICALL Java_crayon_jni_JNITest_get
	(JNIEnv *, jclass){
		return tmp;
}


生成dll动态链接库,并测试,最后时间为:

package crayon.jni;

public class TestJNI {
	public static void main(String[] args) {
		long beginTime = System.currentTimeMillis();
		int i;int j;
		for(i=0;i<1000;i++){
			for(j=0;j<1000;j++){
				JNITest.set(i*j);
				JNITest.get();
			}
		}
		long totalTime = System.currentTimeMillis()-beginTime;
		System.out.println("JNI消耗的总时间(ms):"+totalTime);
	}

}
JNI消耗的总时间(ms):16

 

【JNA实现】

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

#ifdef JNATEST_EXPORTS
#define JNATEST_API __declspec(dllexport)
#else
#define JNATEST_API __declspec(dllimport)
#endif

extern "C" {
	JNATEST_API void set(long l);
	JNATEST_API long get();
}

 

#include "stdafx.h"
#include "JNATest.h"

long tmp;
JNATEST_API void set(long l){
	tmp = l;
}
JNATEST_API long get(){
	return tmp;
}

直接写Java端代码调用上述导出的dll文件,注意别忘记引入JNA相关的jar包,代码为:

package crayon.jna;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface JNATest extends Library {
	JNATest INSTANCE = (JNATest) Native.loadLibrary(
	            "D:/CC/Tools_Tool_ITT_StdPrj_Dev/PF_Tools_VOB/Tools_SubTool/src/JNATest/Release/JNATest", JNATest.class);
	public void set(int i);
	public int get();

}


测试代码和结果为:

package crayon.jna;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface JNATest extends Library {
	JNATest INSTANCE = (JNATest) Native.loadLibrary(
	            "D:/CC/Tools_Tool_ITT_StdPrj_Dev/PF_Tools_VOB/Tools_SubTool/src/JNATest/Release/JNATest", JNATest.class);
	public void set(int i);
	public int get();
}
JNA消耗的总时间(ms):2593

 

综上比较:JNI 16ms  << JNA 2593ms!!!性能差距还蛮大的!!

 

本着赤果果地实事求是地态度,我在自己的lenovo 昭阳K46(XP,处理器i3,内存升级4G--实际使用3G)的机器上测试了一下,结果为(取10次平均):JNI 120.5ms   JNA 4535.8ms !!我的本本貌似不是很给力,但测试结果整体趋势差不多!

 

这次试验,本身也有一个收获,就是:在JNI(或JNA)应用中,在Java端,我们会有一个对象,其中调用的方法都会映射到本地代码中,只要我们是同一个Java对象,我们同样可以将一个值在一次本地方法调用中设置到对象里,然后在下一次调用中使用。当然这个值是保存在本地代码中的。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页