2

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

这是我的 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 安全检查?

我没有注意到性能上的任何提升。

4

1 回答 1

6

是否可以使用 jni 增强反射性能?

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

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


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

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

于 2012-09-18T15:15:43.117 回答