bvd*_*vdb 15 java reflection performance
在我的一个应用程序中,我使用以下内容:
public void calculate (String className)
{
...
Class clazz = Class.forName(className);
...
}
Run Code Online (Sandbox Code Playgroud)
该函数被调用几次/秒.大约有10个可能的类名.虽然我确实意识到这个函数中有一些内部缓存,但我认为这个缓存只能在本机级别上使用.
出于这个原因,我开始怀疑是否应该添加自己的缓存.
private static Map<String,Class> classMap;
public void calculate (String className)
{
...
Class clazz = classMap.get(className);
if (clazz == null)
{
clazz = Class.forName(className);
if (classMap == null) classMap = new HashMap<String, Class>(40);
classMap.put(className, clazz);
}
...
}
Run Code Online (Sandbox Code Playgroud)
这会是性能提升还是真的没有区别?
先感谢您
bvd*_*vdb 12
我写了一个小脚本来计算两个函数的执行时间.
这是我使用的Main类.
public class Benchmark
{
public static void main(String... pArgs)
{
// prepare all data as much as possible.
// we don't want to do this while the clock is running.
Class[] classes = {Object.class, Integer.class, String.class, Short.class, Long.class, Double.class,
Float.class, Boolean.class, Character.class, Byte.class};
int cycles = 1000000;
String[] classNames = new String[cycles];
for (int i = 0; i < cycles; i++)
{
classNames[i] = classes[i % classes.length].getName();
}
// THERE ARE 2 IMPLEMENTATIONS - CLASSIC vs CACHING
Implementation impl = new Caching(); // or Classic();
// Start the clocks !
long startTime = System.currentTimeMillis();
for (int i = 0; i < cycles; i++)
{
impl.doStuff(classNames[i]);
}
long endTime = System.currentTimeMillis();
// calculate and display result
long totalTime = endTime - startTime;
System.out.println(totalTime);
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用的经典实现 Class.forName
private interface Implementation
{
Class doStuff(String clzName);
}
private static class Classic implements Implementation
{
@Override
public Class doStuff(String clzName)
{
try
{
return Class.forName(clzName);
}
catch (Exception e)
{
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是第二个使用a HashMap
来缓存Class
对象的实现.
private static class Caching implements Implementation
{
private Map<String, Class> cache = new HashMap<String, Class>();
@Override
public Class doStuff(String clzName)
{
Class clz = cache.get(clzName);
if (clz != null) return clz;
try
{
clz = Class.forName(clzName);
cache.put(clzName, clz);
}
catch (Exception e)
{
}
return clz;
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
结论:
这会是性能提升还是真的没有区别?
如果它产生了显着的差异,我会感到惊讶 - 如果你只是"每秒几次"调用它(而不是比如说一百万次),那么它真的不值得优化.
在承诺这个更复杂的设计之前,你至少应该在基准测试中单独尝试这个.Class.forName
无论如何,我强烈期望将其缓存,并在您的应用中添加更多复杂性并不好.
Class.forName()
做两件事:
第 1 部分非常快。#2 是真正的工作开始的地方(JVM 可能会访问硬盘甚至网络,具体取决于类加载器)。如果您传入相同的参数,那么除了第一次调用之外的所有调用都将永远不会到达第 2 步。
所以不:它可能不值得优化。