比如说,我们有一个本机循环,必须不时地调用JVM对象上的一些登录:
class UsesNative {
void hangle() {...}
void loop() {
while (true) {
if (doNative()) {
handle();
}
}
}
native boolean doNative();
}
与直接从本机代码调用handle()
相比,它的性能如何:
JNIEXPORT void JNICALL
Java_UsesNative_doNative(JNIEnv *env, jobject instance)
{
jclass class = (*env)->FindClass(env, "UsesNative");
jmethodID method = (*env)->GetMethodID(env, class, "handle", "()V");
// Loop has moved from Java to native
for (;;) {
if (condition) {
(*env)->CallVoidMethod(env, instance, method);
}
}
}
一些JVM支持简化的fast JNI calls。在这种情况下,如果doNative()方法回答了FastNative或CriticalNative的限制,那么第一种方式(没有C-to-Java调用)将表现得更好。
另一方面,正如上面提到的@Holger,条件的计算可能对结果产生更大的影响。
最后,@ EJP关于重用FindClass()和GetMethodID()的结果的评论非常重要。这些调用非常慢,不应该在循环中执行。