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。


posted @ 2014-07-27 10:27  码农神说  阅读(192)  评论(0编辑  收藏  举报