尽可能快地制作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个数字显示的滞后不是平滑变化,而是在更改时跳过大部分比例。
答案 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'。静态链接到它。