Reputation: 117
What is the best way to make a Jni as fast as Possible?
I need to call a .dll for a conversation with a cxternal Measurement Box. Atm i do call the values of the Box over a JNI with a static loaded Lib.
public class myJni{
static {
System.loadLibrary("myJniDll");
}
public native double Get4(String para);
}
very simple as you can see.
On C side i use:
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;
}
The Code needs about 20 ms to get the Value of the Com Portunit. The Lag when the value is changing doesn't "feel" good. It is sensible when I change the value that it needs time to go over the Jni.
Has someone got some tweeks to get it to about 10 ms?
@Edit: Gil´s Pointer Skip made a huge impact. Its now less "laggy". Still not as far as i want to but ok.
The Unit on the Com port is a Measurement device that works in a 0.000000 accuracy. So the Lag is shown by the last 4 Numbers not smoothly changing but skipping much of the scale when changed.
Upvotes: 0
Views: 173
Reputation: 718758
Other Answers offer some useful optimizations (viewed in isolation), but I'm pessimistic that they will give you the amount of speed-up that you desire.
If this method really takes 20 milliseconds per call, amortized over a number of calls, then I can confidently predict that the vast majority of that time is spent in either the call to Get4
, or in the call to GetStringUTFChars
. Neither of those can be optimized, so the chances of getting a 50% speedup are (IMO) non-existent.
Upvotes: 1
Reputation: 310875
You don't state which of these methods does anything resembling 'get the value of the Com Portunit', but you don't need to get the native function addresses every time you call this method. They won't change. Stick them into static variables the first time. As a matter of fact you don't need to dynamically load 'my_64.dll' at all. Statically link to it.
Upvotes: 0
Reputation: 3334
You can skip loading the function pointer for each call:
static Get4 _Get4 = NULL;
static FunctionFunc _FunctionFunc2 = NULL;
if(!_Get4)
_Get4 = (Get4)GetProcAddress(hInstLibrary, "my_Get4");
if(!_FunctionFunc2)
_FunctionFunc2 = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");
This will save a ot of time.
Upvotes: 1