在网上曾看到关于MVC框架的性能比较,根据他们的测试,struts1,springMVC,struts2其性能是从高到低,struts2的性能表现是最差的,到底什么原因使struts2在性能表现上如此差强人意,依照友友们的观点主要有以下原因:
1、拦截器的大量使用
2、valueStack的维护
3、OGNL表达式的使用
网上都有相应的解决方案,感兴趣的友友们可以去搜索看看。因为上面列出的三点影响struts2性能的观点,都用了大量的反射,所以我想在这里讨论下反射的性能。好了,费话不多说了,进入主题。
一,定义一个类如下,此类是为了测试创建对象和调用方法使用
class T {
int x, y, z, a, b, c, d, e, f, g, h, i, j, k;
long aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, xx, yy, zz, ll, mm;
T tt, ttt, tttt, ttttt, ttttttt, tttttttt;
public void sayHello() {
x = 9;
}
}
二、下面是测试类
package com.xuch.memory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, SecurityException,
NoSuchMethodException, IllegalArgumentException,
InvocationTargetException {
int max = 1000;
for (int m = 0; m < 6; m++) {
long st = System.currentTimeMillis();
Class clazz = Class.forName("com.xuch.memory.T"); (1)
for (int i = 0; i < max; i++) { (反射)
Object o = clazz.newInstance();
Method me = clazz.getMethod("sayHello"); (reflect method invoke )
me.invoke(o);
}
long et = System.currentTimeMillis();
long start = System.currentTimeMillis();
for (int i = 0; i < max; i++) { (正常)
T t = new T();
t.sayHello(); (normal method invoke)
}
long end = System.currentTimeMillis();
long normal = end - start;
long reflect = et - st;
double rate = 0;
if(normal != 0)
{
rate = (double)reflect /(double) normal ;
}
System.out.println("以下打印信息是根据不同测试方式会做不同的调整");
System.out.println("----------------------------------------------");
System.out.println("创建对象,并进行方法调用,正常和反射间的比较");
System.out.println("只用了一次Class.forName()加载类");
System.out.println(" 此次循环的次数为:" + max);
System.out.println(" 正常方式创建对象,并进行方法调用所用时间的毫秒数:"+normal);
System.out.println(" 反射方式方式创建对象,并进行方法调用所用时间的毫秒数:"+reflect);
System.out.println(" 反射/正常为:"+rate);
System.out.println("----------------------------------------------");
System.out.println();
max*=10;
}
}
}
上面是完整的代码,下面贴下我的测试结果:
1、分别用正常和反射方式创建对象,也就是说代码中标注“正常”和“反射”的FOR循环中都不包括方法的调用,只有对象创建的代码,并且class.forName()方法在for的外边。下面是测试结果:
只用了一次Class.forName()加载类
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:1000
正常方式创建对象所用时间的毫秒数:0
反射方式方式创建对象所用时间的毫秒数:5
反射/正常为:0.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:10000
正常方式创建对象所用时间的毫秒数:0
反射方式方式创建对象所用时间的毫秒数:15
反射/正常为:0.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:100000
正常方式创建对象所用时间的毫秒数:20
反射方式方式创建对象所用时间的毫秒数:85
反射/正常为:4.25
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:1000000
正常方式创建对象所用时间的毫秒数:165
反射方式方式创建对象所用时间的毫秒数:825
反射/正常为:5.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:10000000
正常方式创建对象所用时间的毫秒数:1655
反射方式方式创建对象所用时间的毫秒数:8221
反射/正常为:4.967371601208459
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前先调用了Class.forName()加载类
此次循环的次数为:100000000
正常方式创建对象所用时间的毫秒数:16497
反射方式方式创建对象所用时间的毫秒数:82296
反射/正常为:4.988543371522095
----------------------------------------------
2、其它条件和1一样,这次只不过把Class.forName()方法放在了for的里面
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:1000
正常方式创建对象所用时间的毫秒数:0
反射方式方式创建对象所用时间的毫秒数:10
反射/正常为:0.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:10000
正常方式创建对象所用时间的毫秒数:5
反射方式方式创建对象所用时间的毫秒数:30
反射/正常为:6.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:100000
正常方式创建对象所用时间的毫秒数:20
反射方式方式创建对象所用时间的毫秒数:260
反射/正常为:13.0
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:1000000
正常方式创建对象所用时间的毫秒数:165
反射方式方式创建对象所用时间的毫秒数:2570
反射/正常为:15.575757575757576
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:10000000
正常方式创建对象所用时间的毫秒数:1655
反射方式方式创建对象所用时间的毫秒数:25606
反射/正常为:15.47190332326284
----------------------------------------------
----------------------------------------------
创建对象,正常和反射间的比较
在使用反射前每次都先调用了Class.forName()加载类
此次循环的次数为:100000000
正常方式创建对象所用时间的毫秒数:16545
反射方式方式创建对象所用时间的毫秒数:256077
反射/正常为:15.477606527651858
----------------------------------------------
3、创建对象,并进行方法调用,正常和反射间的比较,这次的测试就如贴上的代码的真实测试,包括创建对象,并进行方法调用。
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:1000
正常方式创建对象,并进行方法调用所用时间的毫秒数:0
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:15
反射/正常为:0.0
----------------------------------------------
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:10000
正常方式创建对象,并进行方法调用所用时间的毫秒数:5
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:45
反射/正常为:9.0
----------------------------------------------
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:100000
正常方式创建对象,并进行方法调用所用时间的毫秒数:20
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:340
反射/正常为:17.0
----------------------------------------------
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:1000000
正常方式创建对象,并进行方法调用所用时间的毫秒数:165
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:3310
反射/正常为:20.060606060606062
----------------------------------------------
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:10000000
正常方式创建对象,并进行方法调用所用时间的毫秒数:1665
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:32856
反射/正常为:19.733333333333334
----------------------------------------------
----------------------------------------------
创建对象,并进行方法调用,正常和反射间的比较
只用了一次Class.forName()加载类
此次循环的次数为:100000000
正常方式创建对象,并进行方法调用所用时间的毫秒数:16690
反射方式方式创建对象,并进行方法调用所用时间的毫秒数:328532
反射/正常为:19.684361893349312
----------------------------------------------
结论:
一,如果只是创建对象,反射所有的时间是正常的5倍(反射创建对象时并不是每次都去加载类)
二,如果只是创建对象,每次反射创建对象时都去加载类,反射所用的时间是正常的15倍(这说明Class.forName是很费时间的)
三,如果创建对象,并调用方法(因为方法里基本上没有做什么操作,这里只是看调用方法这个动作对性能的影响),反射所有的时间是正常的20倍(反射创建对象时并不是每次都去加载类)。
而且用正常方式,只要循环次数相同,其所用时间也基本上在同一数量级。这说明使用反射调用方法要花费很长时间来准备
反射虽然提供了方便,灵活,但其是以性能为代价的
分享到:
相关推荐
首先,"这下没理由嫌Eval的性能差了吧?"这篇文章可能探讨了`System.CodeDom.Compiler.Eval`方法的性能优化,`Eval`常用于执行字符串形式的代码,其性能通常比直接的反射调用更低,但通过特定的优化策略,可能会改善...
调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现...
多层膜反射镜的反射率测量是该领域研究的关键技术之一,通过精确测量反射率,可以评估多层膜的质量以及其在实际应用中的性能表现。 本文提到的测量方法主要关注X射线激光的应用,X射线激光由于具有波长短、单光子...
- **特性**:从紫外区到红外区均有很高的反射率,是唯一一种能够在如此宽广的光谱范围内保持高反射性能的材料。铝膜表面自然形成的氧化铝(Al2O3)层起到了很好的保护作用,增强了膜层的稳定性和耐用性。 - **应用**...
《解理面为反射面腔长差弯曲波导的优化设计》 在半导体激光器领域,尤其是V型腔激光器的设计中,解理面作为反射面的弯曲波导的优化至关重要。这种设计方法旨在减少激光器的损耗,提高其性能。本文主要探讨了以解理...
采用时域有限差分法, 对均匀蛾眼结构(UMS)和双混合蛾眼结构(BHMS)进行仿真, 分析底面直径和高度对反射率的影响规律, 比较了UMS与BHMS的减反射性能。基于反射率曲线和电场强度分布, 分析了BHMS优异的减反射性能。...
- 性能影响:反射操作相比直接调用方法或访问属性,性能较差,因此在性能敏感的代码中应谨慎使用。 - 安全性问题:反射可以访问私有成员,可能导致安全漏洞,因此在处理用户输入时需小心。 - API稳定性:反射可以...
然而,反射的性能通常比直接代码调用要差,因为反射调用涉及较多的间接和动态处理。不过,有几种方法可以优化反射的性能,其中一种有效的方法是使用委托。 委托是一种可以将方法作为参数传递给其他方法的类型。这...
通过MATLAB进行反射阵天线的相位补偿计算,可以高效地探索各种设计变量,以达到最佳的天线性能。在实际工程中,这种计算方法广泛应用于雷达、通信和遥感等领域。对于初学者和专业人士来说,掌握MATLAB在这方面的应用...
S11值在复数平面上表示,其模值反映了反射功率的大小,而相位则反映了反射相对于入射信号的相位差。反射系数可以转换为VSWR,公式如下: \[ |Γ| = \sqrt{\frac{VSWR - 1}{VSWR + 1}} \] 在MATLAB中,我们可以编写...
此外,反射代码可读性较差,易于出错,应谨慎使用。 总结来说,反射是Java中一种灵活的机制,能够让我们在运行时动态操控类和对象。掌握反射的核心代码,可以帮助我们编写更加灵活和功能丰富的程序,但同时也需要...
Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性...然而,由于反射操作涉及到安全性问题,并且性能相对较差,因此在不必要的情况下应避免过度使用反射。
#### 反射性能 反射在Java中主要用于动态获取类的信息并操作类的对象。反射的性能可以通过以下方式优化: - **缓存元数据**: 对于经常使用的类、构造器、方法或字段,应考虑将它们的引用缓存起来,避免每次都需要...
相位敏感光时域反射系统(Phase-Sensitive Optical Time-Domain Reflectometer,简称ϕ-OTDR)是一种基于瑞利后向相干散射和外差检测原理的分布式光纤传感器。它能够对光纤沿线的振动和声音进行实时在线监测和分布式...
本压缩包文件“反射式摊铺机熨平板高度差调整装置.zip”内包含了一份详细的技术资料——“反射式摊铺机熨平板高度差调整装置.pdf”,主要讲解了这种装置的设计原理、工作方式以及调整方法。 1. 设计原理: 反射式...
4. **干涉计算**:利用傅里叶逆变换将频率域的结果转换回空间域,结合相邻层的相位差,计算出整体的透射和反射系数。 5. **结果输出**:最后,源码会计算并输出整个多层膜结构的平均透射率和反射率,这通常是针对...
因为它破坏了Java的封装性,可能会带来安全问题、性能问题,并且代码可读性较差。在使用反射时,应确保安全性、效率以及异常处理,避免因反射错误导致程序崩溃。 以上知识点详细描述了JAVA反射的基本使用方法和操作...
在PCB设计中,反射是影响信号完整性和系统性能的关键因素。反射通常发生在信号线上的阻抗不连续处,例如连接器、过孔、走线宽度变化或端接不匹配等。这些不连续性会导致信号的能量部分反射回源头,产生信号失真,...