gpt4 book ai didi

java - 使用反射调用方法的性能

转载 作者:行者123 更新时间:2023-11-29 03:17:59 25 4
gpt4 key购买 nike

使用反射调用方法与直接调用方法的性能差异是什么?

上下文详细信息:我有一个类,有一些字符串属性,对于某些属性,我必须将值设置为小写或大写(以及一些与之相关的逻辑)。

我有两个选择:

  1. 复制/粘贴 14 个属性的代码。
  2. 或注释这 14 个方法并使用反射找到它们并调用它们(也使用反射)。

当然有选项 2。我的代码将更具可读性和易于维护,但问题是关于性能。我将有数百万(大约 2-3)个实例,如果性能影响不超过 20 秒,我会选择反射选项。

这里有人有这方面的经验吗?

最佳答案

很难给出一个设定值,因为它取决于您系统的许多方面,所以我写了一个类来检查它。

结果让我感到惊讶,对于我的系统来说,通过反射简单地调用方法与静态调用方法相比,非空方法的静态调用要快 10,000 次,空方法要快 1000,000 倍。

我同时使用了两者,以防 java 编译器/vm 优化空方法调用。

代码如下,也可在本要点中找到 - https://gist.github.com/piersy/23b4814eec806b584266

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);
}
}

}

关于java - 使用反射调用方法的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25388938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com