java中的native方法性能到底怎么样?

前言

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方法,不正确的使用可能会导致内存泄漏与性能损失

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值