前言
java中的native方法性能到底怎么样?
第一次写博客,如果写的不好,望见谅,烦请指出问题,虚心学习
先说结论,native 方法性能不如java方法
一、native方法?
主要是java语言本身是无法调用操作系统提供的一些底层特性,比如打开文件,创建线程;本文不再介绍如何去使用JNI,只谈论性能
二、使用步骤
先创建一个具有native方法的类
代码如下(示例):
public class TestJNI {
public int num1;
static {
System.load("/Users/alex/Library/Java/Extensions/TestJNI.jnilib");
}
/**
int转string
*/
public native String intToString(int param);
public native int stringToInt(String param);
/**
他的本质也是给num1属性set值
*/
public native void modifyNum1(int num1);
public void setNum1(int num1) {
this.num1 = num1;
}
}
2.c语言实现
执行命令,编译成.h文件,(要注意,如果你的包名很长,那么你要回到你的包起始位置调用命令)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "com_Alex_io_jni_TestJNI.h"
/*
* Class: com_Alex_io_jni_TestJNI
* Method: intToString
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_Alex_io_jni_TestJNI_intToString
(JNIEnv *env, jobject o, jint j_int)
{
int c_int = (int)j_int;
if (c_int == 0)
{
return (*env)->NewStringUTF(env,"0");
}
char* str = (char*)malloc(sizeof(char) * 20);
int index = 0;
while(c_int != 0)
{
int tmp = c_int % 10;
str[index++] = tmp + 48;
c_int /= 10;
}
str[index] = '\0';
for(int i = 0,j = index - 1,size = index / 2; i < size;i++,j--)
{
str[i] ^= str[j];
str[j] ^= str[i];
str[i] ^= str[j];
}
return (*env)->NewStringUTF(env,str);
}
/*
* Class: com_Alex_io_jni_TestJNI
* Method: stringToInt
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_Alex_io_jni_TestJNI_stringToInt
(JNIEnv *env, jobject o, jstring j_string)
{
char* s = (char*)(*env)->GetStringUTFChars(env,j_string,0);
int c_num = atoi(s);
return (jint)c_num;
}
/*
* Class: com_Alex_io_jni_TestJNI
* Method: modifyNum1
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_Alex_io_jni_TestJNI_modifyNum1
(JNIEnv *env, jobject o, jint j_int)
{
jclass class = (*env)->GetObjectClass(env,o);
jfieldID id = (*env)->GetFieldID(env,class,"num1","I");
(*env)->SetIntField(env,o,id,j_int);
}
3.前两个方法主要是int转string,或int转string,有兴趣可关注下,主要谈第三个方法
第三个方法主要是为变量num1进行赋值,我们看下调用java方法和native方法赋值的性能如何
,看下测试代码
public class MyTest {
public static void main(String[] args) {
TestJNI testJNI = new TestJNI();
// String s = testJNI.intToString(434343220);
// int s = testJNI.stringToInt("1234567890");
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
testJNI.modifyNum1(50);
}
System.out.println("调用native method(10w次) 耗时:" + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
testJNI.setNum1(50);
}
System.out.println("调用java method(10w次) 耗时:" + (System.currentTimeMillis() - start));
System.out.println(testJNI.num1);
}
}
结果:
调用native method(10w次) 耗时:25
调用java method(10w次) 耗时:1
50
进程已结束,退出代码 0
总结
可以看出性能差距比较大,native方法主要还是用于一些对于操控操作系统,对内存操作的算法上,通常可以用java实现的,还是不要用native方法,不正确的使用可能会导致内存泄漏与性能损失