java 反射性能测试

一直听别人说java 的反射机制很慢,尽量别用。之后笔者进入一个新的公司,熟悉系统的时候,发现系统的核心跳转实现用的是asm代理,而不是使用反射(反射的实现更简单),当时笔者就问了下作者,作者说是为了提高性能。当时我就心想,反射到底慢到了什么程度,弄的人谈虎色变,于是笔者就做了一个测试,测试下反射,看到底慢到了什么程度。

测试代码如下:


package com.sohu.smc.yueExam;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
 * 测试反射的性能
 * @author shaojieyue
 *
 */
public class TeflectPerformanceTest {

	private long count;//循环执行的次数
	public void exec() throws Exception{
		long end = 0L;
		long start=0L;
		String str="abcde";
		Method method=null;
		String methodName="replace";
		String[] args={"abc","abc"};
		method= String.class.getDeclaredMethod(methodName, CharSequence.class,CharSequence.class);
		start=System.currentTimeMillis();
		for(long i=0;i<count;i++){
			method.invoke(str,args);
		}
		end=System.currentTimeMillis();
		System.out.println("--->反射执行时间(有缓存Method): "+date(end-start));
		
		start=System.currentTimeMillis();
		for(long i=0;i<count;i++){
			invokeNoCache(methodName,str,args);
		}
		end=System.currentTimeMillis();
		System.out.println("--->反射执行时间(无缓存): "+date(end-start));
		start=System.currentTimeMillis();
		for(long i=0;i<count;i++){
			str.replace("abc","abc" );
		}
		end=System.currentTimeMillis();
		System.out.println("--->传统执行时间: "+date(end-start));
		
	}
	
	private String date(long millis){
		SimpleDateFormat formatter = new SimpleDateFormat("HH小时mm分钟ss秒");
		formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
		String hms = formatter.format(millis);
		return hms;
	}
	
	/**
	 * 非缓存的方式调用
	 * @param methodName
	 * @param target
	 * @param args
	 * @throws Exception
	 */
	private void invokeNoCache(String methodName,String target,String[] args) throws Exception{
		Method method= String.class.getDeclaredMethod("replace", CharSequence.class,CharSequence.class);
		method.invoke(target,args);
	}
	
	public static void main(String[] args) throws Exception {
		long count=Long.valueOf(args[0]);
		TeflectPerformanceTest tpt = new TeflectPerformanceTest();
		tpt.count=count;
		tpt.exec();
	}
}


测试参数:300000000 三千万次

测试结果:

--->反射执行时间(有缓存Method): 00小时01分钟42秒
--->反射执行时间(无缓存): 00小时03分钟25秒
--->传统执行时间: 00小时01分钟41秒


从结果可以看出,反射并不是传言中的那么慢(据说是java 1.3版时做了一次反射性能的提升,之前是很慢的),如果是有缓存Method对象的情况下,invoke调用和传统方式的调用是没有什么差别的,而不采用缓存的方式(每次都重新获取Method),时间大概是传统调用方式的两倍。

PS:有人说,系统框架对系统性能的影响是很微弱的,大部分性能的瓶颈都是在系统业务本身,和数据库方面。

笔者感觉有一定的道理(不是任何时候都对,实际情况实际出发),不知道各位怎么看?

你可能感兴趣的:(java 反射性能测试)