JNI上的运行时

时间:2014-08-29 09:31:22

标签: java c dll java-native-interface

尽可能快地制作Jni的最佳方法是什么?

我需要调用.dll与cxternal Measurement Box进行对话。 Atm我确实用一个静态加载的Lib调用了JNI上Box的值。

     public class myJni{

        static {
            System.loadLibrary("myJniDll");
        } 
       public native double     Get4(String para);
    }
你可以看到非常简单。

在C方面,我使用:

HINSTANCE hInstLibrary = LoadLibrary("my_64.dll");
typedef void(*FunctionFunc)();

JNIEXPORT jdouble JNICALL my_Get4
(JNIEnv * penv, jclass clazz, jstring Para)
{
    typedef double(__stdcall *Get4)(char FAR *lpszPara); 

    Get4 _Get4;
    FunctionFunc _FunctionFunc2;

    _Get4 = (Get4)GetProcAddress(hInstLibrary, "my_Get4");
    _FunctionFunc2 = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");

    const char *nativeString = penv->GetStringUTFChars(Para, 0);

    const char* parameter = nativeString; 

    double ret = _Get4((char*)parameter); 

    penv->ReleaseStringUTFChars(Para, nativeString);  

    return ret;


}

代码需要大约20毫秒才能获得Com Portunit的价值。价值变化时的滞后并不“感觉”好。当我改变价值需要时间来审视Jni时,这是明智的。

是否有人得到一些推文才能达到约10毫秒?

@Edit:Gil的Pointer Skip产生了巨大的影响。它现在不那么“滞后”了。仍然不是我想要的,但还可以。

Com端口上的单元是一种测量设备,其精度为0.000000。因此,最后4个数字显示的滞后不是平滑变化,而是在更改时跳过大部分比例。

3 个答案:

答案 0 :(得分:1)

您可以跳过为每个调用加载函数指针:

static Get4 _Get4 = NULL;
static FunctionFunc _FunctionFunc2 = NULL;

if(!_Get4)
  _Get4 = (Get4)GetProcAddress(hInstLibrary, "my_Get4");

if(!_FunctionFunc2)
_FunctionFunc2 = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");

这将节省大量时间。

答案 1 :(得分:1)

其他答案提供了一些有用的优化(孤立地看),但我很悲观,他们会给你你想要的加速量。

如果这个方法每个呼叫真的需要20毫秒,通过多次调用分摊,那么我可以自信地预测那个时间的绝大多数花费在对{{1}的调用上},或致电Get4。这些都不能被优化,因此获得50%加速的机会(IMO)不存在。

答案 2 :(得分:0)

您没有说明这些方法中的哪一个做了类似'获取Com Portunit的值'的内容,但是每次调用此方法时都不需要获取本机函数地址。他们不会改变。第一次将它们粘贴到静态变量中。事实上,你根本不需要动态加载'my_64.dll'。静态链接到它。