Java 使用jni可以提高反射性能吗?

Java 使用jni可以提高反射性能吗?,java,reflection,java-native-interface,Java,Reflection,Java Native Interface,在我的代码中,我做了很多反射查找,所以我试图以某种方式改进它 这是我的jni setter方法的一个示例: JNIEXPORT jobject JNICALL Java_org_orman_mapper_Model_fieldSetFloat(JNIEnv * env, jobject obj, jobject model, jstring field_name, jstring field_type, jfloat value, jclass clazz) { const char

在我的代码中,我做了很多反射查找,所以我试图以某种方式改进它

这是我的jni setter方法的一个示例:

JNIEXPORT jobject JNICALL 
Java_org_orman_mapper_Model_fieldSetFloat(JNIEnv * env, jobject  obj, jobject model, jstring field_name, jstring field_type, jfloat value, jclass clazz)
{
    const char* utf_string_name = (*env)->GetStringUTFChars (env, field_name, 0);
    const char* utf_string_type = (*env)->GetStringUTFChars (env, field_type, 0);

    jfieldID id = (*env)->GetFieldID(env, clazz, utf_string_name, utf_string_type);
    (*env)->SetFloatField(env, model, id, value);
    return model;
}
调用的本质,如
SetFloatField
,是否跳过任何java安全检查

我没有注意到在表现上有任何进步

使用jni可以提高反射性能吗

可能有一点。但是,虽然您可以消除“不需要的”访问检查,但由于必须进行JNI调用才能访问对象的内部,因此您会丢失一些检查。相比之下,反射方法及其调用序列的实现可以以常规JNI方法所不具备的方式进行优化

(例如,它们可以实现为直接访问相关数据结构,而不是使用独立于平台的JNI API。或者JIT编译器可以处理对某些“内在”的本机方法调用。)本机方法作为特例…并使用更快的调用序列。请注意,这都是假设的…但在某些JVM中,对一些核心方法的本机实现进行了特殊处理,以使它们更快。)


但我的建议是,如果用常规的非反射性Java代码替换反射性代码,无论是手写代码、作为源代码生成并编译的代码,还是作为字节码生成的代码,都会获得更好的性能(数量级或更高)。一旦有了字节码,JIT编译器将能够生成优化的本机代码,这将比使用反射或JNI快得多


因此,与其用JNI代码替换反射(及其相关问题),不如用使用纯字节码的东西替换反射。

我认为
GetStringUTFChars
是迄今为止最昂贵的函数。你能在这里缓存
jfieldID
吗?如果要绕过安全性,可以调用
Member.setAccessible(true)
跳过安全检查,因此即使您有访问权限,它也会更快。@PeterLawrey这就是我现在看到的。不确定它比JNI快,但这是一种用最少的努力加快反射速度的方法。;)根据JVM及其使用方式,您可以查看更快的MethodHandles。@PeterLawrey MethodHandles来自jdk7,是吗?不幸的是,我仅限于版本6。我不确定在任何情况下设置字段都会更快。你是说在运行时生成字节码?我读到一篇文章说这是一个解决方案,但我发现它很难实现。如果我能通过字节码操作设置一个字段,我敢打赌。我同意斯蒂芬的观点。我看不出有任何理由用JNI编写这段代码。您可以在大约四行Java代码中完成,应用程序的性质将决定是在编译时、加载时还是运行时生成。如果直接字节码生成太难,请考虑其他替代方案。