JNI只C性能测试
深入学习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 <stdio.h> #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<len;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 <stdio.h> #include <sys/time.h> 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。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。