`
xu-ch
  • 浏览: 1104 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

反射性能到底会差多少

阅读更多

    在网上曾看到关于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倍(反射创建对象时并不是每次都去加载类)。

而且用正常方式,只要循环次数相同,其所用时间也基本上在同一数量级。这说明使用反射调用方法要花费很长时间来准备

 

反射虽然提供了方便,灵活,但其是以性能为代价的 

 

 

分享到:
评论

相关推荐

    java_反射实战代码

    调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现...

    论文研究-基于反射变异策略的自适应差分进化算法.pdf

    针对差分进化算法易于陷入早熟收敛和局部搜索较慢的问题,提出了一种...使用12个函数测试了RMADE的性能并与其他算法进行比较,结果表明RMADE具有较快的收敛速度和较好的全局探测能力,进而体现了反射变异策略的价值。

    均匀与混合蛾眼结构减反射性能的模拟

    采用时域有限差分法, 对均匀蛾眼结构(UMS)和双混合蛾眼结构(BHMS)进行仿真, 分析底面直径和高度对反射率的影响规律, 比较了UMS与BHMS的减反射性能。基于反射率曲线和电场强度分布, 分析了BHMS优异的减反射性能。...

    适用于北斗GNSS-R接收机的反射信号捕获算法

    针对北斗反射信号捕获难度大问题,提出一种...对新算法进行了MATLAB仿真,并与传统的捕获算法(相干非相干算法、差分相干算法)做了比较,仿真结果表明,该算法在捕获性能上明显优于传统的相干非相干与差分相干捕获算法。

    Java反射使用总结

    反射非常强大和有用,很多java框架中都有反射的影子,例如spring、mybatis等等,JDBC利用反射将数据库的表字段映射到java对象的getter/setter方法。Jackson,GSON,Boon等类库也是利用反射将JSON文件的属性映射到java...

    论文研究 - 使用荧光和反射光谱预测秋葵(

    RPDval = 1.61(rP = 0.718)和RPDval = 1.46(rP = 0.56)的P和N产量预测性能分别较差。 这项研究证明了荧光和反射光谱法用于准确估算叶片中大量营养成分和作物产量的潜力。 从产生的光谱带获得的高选择性可以导致...

    反射式转镜干涉光谱仪光程差计算

    光程差的研究对于干涉光谱仪的性能指标分析、设计和研制具有重要意义。在介绍反射式转镜干涉光谱仪的原理基础上,描述了利用基于马吕斯定律的光线追迹法和基于镜面成像原理的像点法分析其光程差的方法。利用光线追迹...

    宁夏宝丰能源集团80焦性能预测

    基于模糊集合配煤方法,结合80焦配合煤的实测镜质体数值型反射率和活惰比数据,计算强度指数SI和组成平衡指数CBI两个数值,通过剩余标准差推定完全二次二元二项式回归方程为最佳回归方程,用相对应的焦炭反应性CRI、焦炭...

    PEG改性SiO改善抗反射涂层的环境稳定性

    由于通过溶胶-凝胶法制备的抗反射涂层的环境稳定性较差,因此采用溶胶改性的方法来改善其性能。 以原硅酸四乙酯(TEOS)为前体,以氨水为催化剂(含量约28%),在乙醇溶剂中制备碱性硅溶胶。 使用聚乙二醇(PEG200...

    模糊集合度量配煤方法在昆钢焦炭性能预测的应用

    用剩余标准差推定完全二次二元二项式回归方程为最佳回归方程,以SI、CBI为自变量,用相对应的焦炭反应性CRI、焦炭反应后强度CSR、焦炭抗碎强度M40和焦炭耐磨强度M10进行回归分析,利用MATLAB软件绘制其相应的可视曲面和...

    偏振分光镜分光性能非理想对激光外差干涉非线性误差的影响

    推导出非理想情况下偏振分光镜透射率和反射率的激光外差干涉非线性误差模型,建立了偏振分光镜分光性能非理想对非线性误差二次谐波的影响模型。仿真结果表明,偏振分光镜的透射率和反射率非理想对非线性误差的影响为...

    四频差动激光陀螺差分偏振损耗研究

    差分偏振损耗所导致的零偏直接影响四频差动激光陀螺性能。基于此,提出一种通过优化反射镜配置参数来有效减小差分偏振损耗的方法。基于琼斯矩阵,通过求解自洽方程,数值分析了四频差动激光陀螺反射镜参数及非共面折叠...

    高速数字PCB互连设计信号完整性研究

    单端拐角中的45"外斜切结构具有更好的传输性能,差分拐角的长度不匹配会引入差分噪声,差分噪声的大小与信号上升时间有关;地平面开槽造成回路电感增加,引入不连续,设计中应避免参考平面的开槽"总之,由仿真和分析结果...

    光伏电池表面抛物锥阵列微结构的反射特性研究

    采用时域有限差分法(FDTD)对硅基太阳能电池表面抛物锥阵列微结构的反射特性进行研究,分析了抛物锥阵列的高度、底面占空比、周期等参数对其抗反射性能的影响。研究表明,反射率随底面占空比、高度的增大而减小。在锥...

    基于全反射的波导异质结构单向传输性能研究

    基于全反射原理设计了两种由二氧化硅和锗材料构筑的三角晶格光子晶体波导异质结构, 运用时域有限差分法对该结构在宽频带内的单向传输特性进行分析。通过改变正向出射端波导宽度对结构进一步优化, 实现了在异质结构...

    金属介质组合270°反射式宽带相位延迟膜设计

    对激光实现由线偏振光转变成圆偏振光的偏振态调制,需要引入90°或270°相位延迟器。...通过误差分析可知,在现有膜厚控制精度下,控制敏感层容差,在设计带宽内可得到反射率R≥99.9%和相位延迟偏差δ&lt;7.2°。

    碳污染清洗工艺对极紫外光刻光学元件反射率的影响

    极紫外光刻系统中的碳污染会降低多层膜反射率,在保证光学元件性能的前提下,如何选择碳清洗工艺是一项重要课题。通过对不同清洗工艺的原理分析,揭示了不同工艺对多层膜反射率的影响主要体现在膜层氧化、刻蚀及表面...

    BetterReflection:更好的反射是一种反射API,旨在改善和提供比PHP内置反射API更多的功能

    更好的反思 更好的体现是一种反射API,旨在改善和提供更多的功能比PHP的内置 。... 更好的体现是不适合的运行时间使用,因为性能比PHP内置反射差很多。 如果您不想做本机PHP反射不能做的任何事情,那么就使用本机PHP反

    非偏振分光镜对外差干涉仪非线性误差的影响

    除了激光源、偏振分光镜(PBS)和波片等偏振器件之外,非偏振分光镜(NPBS)也是外差干涉...为了实现纳米/亚纳米级精度的外差干涉测量,选择性能稳定的NPBS,特别是NPBS退偏效应与激光源输出偏振态之间的匹配非常重要。

    双层光栅结构减小非晶硅薄膜太阳电池的反射

    使用时域有限差分(FDTD)方法模拟了反射和透射场的强度分布。模拟结果显示,与无光栅的常规非晶硅薄膜太阳电池相比,所设计的太阳电池结构可以将光的吸收率提高39.2%,短路光电流密度提高19.9%,这些结果优于文献中所...

Global site tag (gtag.js) - Google Analytics