深入学习JNI之前,介绍一个比较好的学习文档:jni详细教程。我这里只是一个Demo测试性能,至于入门教程请看我前一篇博文。

Demo展示

这个Demo用于从小到大的冒泡排序,App.java代码:

package net.oseye.JniDemo;

public class App

{

public static void main( String[] args )

{

int[] nums={2,6,9,18,5,7};

Sort sort=new Sort();

//调用native方法

int[] res=sort.bubble(nums,nums.length);

for(int i:res){

System.out.print(i+"\t");

}

}

}

class Sort{

static{

System.loadLibrary("sort");

}

/*

* 声明native方法

*/

public native int[] bubble(int[] nums,int len);

}

c++代码:

#include

#include "net_oseye_JniDemo_Sort.h"

JNIEXPORT jintArray JNICALL Java_net_oseye_JniDemo_Sort_bubble

(JNIEnv *env, jobject obj, jintArray arr, jint n)

{

jintArray iarr = (*env)->NewIntArray(env, n);

jint num[n];

(*env)->GetIntArrayRegion(env, arr, 0, n, num);

int i, j;

for(i = 0; i < n; i++)

{

for(j = 0; i + j < n - 1; j++)

{

if(num[j] > num[j + 1])

{

int temp = num[j];

num[j] = num[j + 1];

num[j + 1] = temp;

}

}

}

(*env)->SetIntArrayRegion(env, iarr, 0, n, num);

(*env)->ReleaseIntArrayElements(env, arr, num, 0);

return iarr;

}

执行输出:

2 5 6 7 9 18

Java和c/c++数据类型转换是一个学习重点,还有关于内存分配与释放以及异常抛出等,参考官方文档。

性能测试

成功执行上面的Demo,你一定信心满满,以后可以把Java和C/C++结合来用,Java的便捷+C/C++高性能,但下面的测试会让你非常有挫折感。

我添加一个Java方法:jbubble也用于从小到大的冒泡排序,App.java代码:

package net.oseye.JniDemo;

public class App

{

public static void main( String[] args )

{

//初始化数组

int len=10000;

int[] nums=new int[len];

for(int i=0;i

nums[i]=(int) Math.round(Math.random() * len);

}

Sort sort=new Sort();

//调用native方法

long start=System.currentTimeMillis();

sort.bubble(nums,nums.length);

System.out.println("c cost time:"+(System.currentTimeMillis()-start));

start=System.currentTimeMillis();

sort.jbubble(nums,nums.length);

System.out.println("j cost time:"+(System.currentTimeMillis()-start));

}

}

class Sort{

static{

System.loadLibrary("sort");

}

/*

* 声明native方法

*/

public native int[] bubble(int[] nums,int len);

/**

* java sort

* @param nums

* @param len

* @return

*/

public int[] jbubble(int[] nums,int len){

int i, j;

for(i = 0; i < len; i++)

{

for(j = 0; i + j < len - 1; j++)

{

if(nums[j] > nums[j + 1])

{

int temp = nums[j];

nums[j] = nums[j + 1];

nums[j + 1] = temp;

}

}

}

return nums;

}

}

执行输出:

c cost time:453

j cost time:125

是不是吓你一跳,好不容易把Java和c/c++结合了,却给了这个结果:结合了C/C++比原生的JAVA慢了3倍左右,严重被挫折了!!!

由于目前对C/C++操作不熟练,不方便实验,但从网上查的别人总结大致:不管是java/native还是native/java都比java/java慢,主要是把时间消耗在调用过程转换上了,在把控制权和入口切换给本地方法之前,VM必须做一些额外的操作来创建参数和栈帧。

有兴趣的童鞋可以自己尝试下,看看时间到底去哪儿了?

我本来也想试试的,但c++在windows下获取当前时间的毫秒数我弄的总是不对,如:

#include

#include

long getCurrentTime()

{

struct timeval tv;

gettimeofday(&tv,NULL);

long res= tv.tv_sec * 1000 + tv.tv_usec / 1000;

return res;

}

int main()

{

printf("%ld\n",getCurrentTime());

return 0;

}

这个在linux下是OK的,但在windows下总是不对,这难道就是体现了平台差异?! 暂时放弃实验,放弃JNI。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐