原文出处

一直以来都对Java反射究竟消耗了多少效率很感兴趣,今晚总算有空进行了一下测试

测试被调用的类和方法

package com.spring.scran;

public class TestMethod {

public void test() {
for(int i = 0 ; i < 10; i ++) {
System.out.print("");
}
}

/**
* 下面几个方法没什么用的,就放着模拟几个类
*/
public void test2() {
for(int i = 0 ; i < 10000; i ++) {
System.out.print("");
}
}

public void test3() {
for(int i = 0 ; i < 10000; i ++) {
System.out.print("");
}
}
public void test4() {
for(int i = 0 ; i < 10000; i ++) {
System.out.print("");
}
}
}

测试方法的类

package com.spring.aop.test;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.spring.scran.TestMethod;

public class TestXiao {

private long start;

private int methodCount = 10000000;

private static Map<String, Method> map = new HashMap<>();

@Before
public void before(){
start = System.currentTimeMillis();
}

@After
public void after() {
System.out.println(System.currentTimeMillis() - start);
}

/**
* 普通方法
*/
@Test
public void test1() {
TestMethod method = new TestMethod();
for(int i = 0 ; i < methodCount ; i ++) {
method.test();
}
}

/**
* 反射执行方法
* @throws Exception
*/
@Test
public void test2() throws Exception{
TestMethod method = new TestMethod();
for(int i = 0 ; i < methodCount ; i ++) {
method.getClass().getMethod("test").invoke(method);
}
}

/**
* 模拟将反射得到的 Method 方法放到缓存中
* @throws Exception
*/
@Test
public void test3() throws Exception{
TestMethod testMethod = new TestMethod();
for(int i = 0 ; i < methodCount ; i ++) {
Method method = map.get("test");
if(method != null) {
method.invoke(testMethod);
} else {
method = testMethod.getClass().getMethod("test");
map.put("test", method);
method.invoke(testMethod);
}
}
}
}

测试结果
  普通方法 反射方法 反射加模拟缓存
第一次 8730 10368 9111
第二次 8833 10402 9184
第三次 8893 10290 9057

根据测试结果来看,可以看出普通执行的方法确实是比反射快点,当然,这真是一个简单的测试,当反射次数越多,消耗的性能肯定就越大

同时可以看到如果把反射得到的 method 放到缓存中,那么反射执行就和普通方法差不多了,所以尽可能的把Method 放到缓存中。

总结:

反射多少会有性能损耗,但一般可以忽略,而java对javabean方面的反射支持,java底层都有PropertyDescriptor和MethodDescriptor支持,可以一定程度的减少反射消耗。 AOP方面,cglib是通过类的字节码生成其子类去操作的,一旦子类生成就是纯粹的反射调用,不再操作字节码了,而一般AOP调用是在单例上,不会频繁的去用cglib生成子类。

反射用得最多的应该就是赋值注入,像数据库表映射为JavaBean等。

反射多少会有性能损耗,但一般可以忽略,而java对javabean方面的反射支持,java底层都有PropertyDescriptor和MethodDescriptor支持,可以一定程度的减少反射消耗。 AOP方面,cglib是通过类的字节码生成其子类去操作的,一旦子类生成就是纯粹的反射调用,不再操作字节码了,而一般AOP调用是在单例上,不会频繁的去用cglib生成子类。

反射用得最多的应该就是赋值注入,像数据库表映射为JavaBean等。

绝大部分系统的性能瓶颈还远远没有到需要考虑反射这里,逻辑层和数据层上的优化对性能的提升比优化反射高n个数量级。

框架的设计是性能、标准和开发效率等多个方面的权衡。

最新文章

  1. ubuntu 更改时区
  2. c# datagridview 中DataSource的使用总结
  3. html5 canvas(小树姐的牛掰到爆了的作品)
  4. jade学习01
  5. 单元测试_JUnit4的应用与实践
  6. ubuntu安装最新版本的node.js
  7. .Net 下FCKeditor上传图片加水印
  8. 【原】K3Cloud平台开发之Python插件
  9. samba常用命令
  10. (转)C# WinForm中 获得当前鼠标所在控件 或 将窗体中鼠标所在控件名显示在窗体标题上
  11. OpenGL------三维变换
  12. 基于FPGA的肤色识别算法实现
  13. vs代码模板制作
  14. Xamarin Essentials教程磁力计Magnetometer
  15. TypeScript 之 书写.d.ts文件
  16. Spring全家桶系列–[SpringBoot入门到跑路]
  17. smarty详细使用教程(韩顺平smarty模板技术笔记)
  18. Spark记录-Scala异常处理与文件I/O
  19. SQL已存在则更新不存在则插入
  20. ACM-ICPC 2018 徐州赛区网络预赛 Solution

热门文章

  1. 网站建设中常用的JS代码段落
  2. jquery ajax基本用法
  3. 基于Axis1.4的webservice接口开发(代码开发)
  4. python pip list 命令列出所有安装包和版本信息
  5. 关于JavaScript的数组随机排序
  6. bzoj1635 / P2879 [USACO07JAN]区间统计Tallest Cow
  7. SIFT在OpenCV中的调用和具体实现(HELU版)
  8. STM32唯一的ID
  9. Java求两个数平均值
  10. Eclipse的快捷键使用总结