Java 使用反射调用方法的性能
使用反射调用方法与直接调用方法的性能差异是什么 上下文详细信息: 我有一个类,具有一些字符串属性,对于某些属性,我必须将值设置为小写或大写(以及一些与此相关的逻辑) 我有两个选择:Java 使用反射调用方法的性能,java,reflection,Java,Reflection,使用反射调用方法与直接调用方法的性能差异是什么 上下文详细信息: 我有一个类,具有一些字符串属性,对于某些属性,我必须将值设置为小写或大写(以及一些与此相关的逻辑) 我有两个选择: 复制/粘贴14个属性的代码 或者注释这14个方法并使用反射找到它们并调用它们(也使用反射) 当然有选择2。我的代码可读性更好,维护也更容易,但问题是性能。我将有数百万(大约2-3个)的实例,如果对性能的影响不超过20秒,我将使用反射选项 这里有人有这方面的经验吗 一般来说,是的,反射速度较慢。如果你所说的数百万次呼叫
这里有人有这方面的经验吗 一般来说,是的,反射速度较慢。如果你所说的数百万次呼叫是指数百万次呼叫,那么是的,在某些情况下,你可能会产生超过20秒的开销。在某些情况下,您可能不会产生额外的开销,因为编译器将能够对其进行优化。您必须给出更多关于如何使用反射的详细信息,或者自己运行反射。我的直觉告诉我,在300万个电话中,你的开销不会超过20秒,但这是一种直觉。让我们从网络反思的一些缺点开始 反射的缺点 反射很强大,但不应不加区别地使用。如果是 如果可以在不使用反射的情况下执行操作,则 最好避免使用它。应保持以下关注事项 在通过反射访问代码时请记住 性能开销,因为反射涉及 通过动态解析,某些Java虚拟机优化可以 不能执行。因此,反射操作的速度较慢 性能优于非反射型,且应 避免在中经常调用的代码段中使用 性能敏感的应用程序 安全限制 反射需要运行时权限,该权限在运行时可能不存在 在安全经理的领导下。这是我们的一个重要考虑因素 必须在受限安全上下文中运行的代码,例如 小程序 内部构件的暴露 因为反射允许代码执行非反射代码中非法的操作,例如 访问私有字段和方法时,可能会导致反射的使用 在意外的副作用,这可能导致代码功能失调和 可能会破坏便携性。反射代码打破了抽象和抽象 因此,可能会随着平台的升级而改变行为 因此,您可以确信,一旦开始扩展,性能将成为一个问题。 但是,如果您能够承受性能开销,直觉告诉您,对于大写/小写操作,性能开销不应超过20秒,并且具有巨大的可伸缩性不是一个问题,那么您可以使用它。但要注意,对绩效的直觉通常都是错误的。所以你肯定想测试一下 一定要为您想要的任务查找面向方面的编程
我的意见是:使用AOP框架。很难给出一个固定的数字,因为它将取决于系统的许多方面,所以我编写了一个类来检查这一点 结果让我惊讶,对于我的系统来说,通过反射简单调用方法与静态调用方法相比,非空方法的静态调用速度要快10000倍,空方法的静态调用速度要快1000000倍 我使用了这两种方法,以防java编译器/vm优化掉一个空方法调用 代码如下,也可在本要点中找到-
import java.lang.reflect.InvocationTargetException;
导入java.lang.reflect.Method;
公共类测试反射{
公共静态长INC=0;
公共静态最终整数计数=100000000;
私有静态类虚拟{
公共void doSomething(字符串s1、字符串s2、字符串s3){
INC++;
}
}
公共静态void main(字符串[]args)引发NoSuchMethodException{
虚拟对象=新虚拟对象();
方法Method=obj.getClass().getMethod(“doSomething”,String.class,String.class,String.class);
String s1=“string1”;
String s2=“string2”;
String s3=“string3”;
//热身
运行反射(obj,方法,s1,s2,s3,计数/10);
运行静态(obj、s1、s2、s3、计数/10);
///房地产
long reftime=System.nanoTime();
运行反射(obj,方法,s1,s2,s3,计数);
reftime=System.nanoTime()-reftime;
长时间=System.nanoTime();
运行静态(obj、s1、s2、s3、计数);
时间=System.nanoTime()-时间;
System.out.println(reftime);
系统输出打印LN(时间);
//每秒1000*1000*1000纳秒
系统输出打印项次(参考时间/(1000*1000*1000));
系统输出打印项次(时间/(1000*1000*1000));
系统输出打印项次((双)参考时间/(双)时间);
System.out.println(“使用反射降低的速度百分比:”+((双)参考时间/(双)时间)-1)*100);
}
私有静态void runReflection(虚拟对象、方法、字符串s1、字符串s2、字符串s3、int计数){
for(int i=0;i
反射成本很高。你可以找到
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflection {
public static long INC = 0;
public static final int COUNT = 100000000;
private static class Dummy {
public void doSomething(String s1, String s2, String s3) {
INC++;
}
}
public static void main(String[] args) throws NoSuchMethodException {
Dummy obj = new Dummy();
Method method = obj.getClass().getMethod("doSomething", String.class, String.class, String.class);
String s1 = "string1";
String s2 = "string2";
String s3 = "string3";
//warmup
runReflection(obj, method, s1, s2, s3, COUNT / 10);
runStatic(obj, s1, s2, s3, COUNT/10);
///realtest
long reftime = System.nanoTime();
runReflection(obj, method, s1, s2, s3, COUNT);
reftime = System.nanoTime() - reftime;
long time = System.nanoTime();
runStatic(obj, s1, s2, s3, COUNT);
time = System.nanoTime() - time;
System.out.println(reftime);
System.out.println(time);
//1000 *1000 *1000 nanoseconds in a second
System.out.println(reftime / (1000 *1000 *1000));
System.out.println(time / (1000 *1000 *1000));
System.out.println((double)reftime/ (double)time );
System.out.println("percentage speed decrease from using reflection:"+(((double)reftime/(double)time)-1)*100);
}
private static void runReflection(Dummy obj, Method method, String s1, String s2, String s3, int count) {
for (int i = 0; i < count; i++) {
try {
method.invoke(obj, s1, s2, s3);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
}
private static void runStatic(Dummy obj, String s1, String s2, String s3, int count) {
for (int i = 0; i < count; i++) {
obj.doSomething(s1,s2,s3);
}
}
}