「java反射优化」jdk对反射的优化
今天给各位分享java反射优化的知识,其中也会对jdk对反射的优化进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、Java反射的性能为什么比直接调用慢一个数量级左右
- 2、java反射的性能为什么低
- 3、Java 反射到底慢在哪里?
- 4、什么是反射?什么Java反射?
- 5、java课程分享Java的反射机制
- 6、Java 方法反射机制
Java反射的性能为什么比直接调用慢一个数量级左右
反射肯定比直接调用慢
这个毋庸置疑了,我这篇文章也不是证明反射有多高效的。
现在的快递哥很火,那我们就举个快递的例子。如果快递员就在你住的小区,那么你报一个地址:xx栋xx号,那么快递员就可以马上知道你在哪里,直接就去到你家门口;但是,如果快递员是第一次来你们这里,他是不是首先得查查百度地图,看看怎么开车过去,然后到了小区是不是得先问问物管xx栋怎么找,然后,有可能转在楼下转了两个圈才到了你的门前。
我们看上面这个场景,如果快递员不熟悉你的小区,是不是会慢点,他的时间主要花费在了查找百度地图,询问物业管理。OK,反射也是一样,因为我事先什么都不知道,所以我得花时间查询一些其他资料,然后我才能找到你。大家有兴趣可以查看反射的实现原理,以及MetaData的相关概念。
反射到底比直接调用慢多少?
好了,我们知道反射肯定慢的,那么是不是反射就不能用了呢?有些人一听到慢,就非常着急的下结论,反射怎样怎样不行,怎样怎样不能用。但是,同学,反射到底比直接调用慢多少,你造吗,能给我个实际的数据吗?很多人其实对性能只有个模糊的概念,而没有数值支撑。之前我给同事找了一个动态解析表达式的类库,他觉得不太好用,他很聪明,很快的找到了用DataTale.Compute可以实现公式的动态解析。我问他,这个方法和我给的类库性能上有什么区别?他跟我说,这个已经很快了,执行1秒都不到。我一听,就觉得不对劲,你的思想还停留在秒级,跟我谈什么性能?
怎么去判断一个函数的性能?因为函数的执行太快太快了,你需要一个放慢镜,这样才能捕捉到他的速度。怎么做?把一个函数执行一百万遍或者一千万遍,你才能真正了解一个函数的性能。也就是,你如果想判断性能,你就不能还停留在秒级,毫秒级的概念,你必须用另外一个概念替代,才能知道真正的性能。结果我同事把这两种方法执行了100w遍,确实,我提供的类库比他的快了8秒。
好了,现在拿我早两天提供的工厂方法来做测试,其中CodeTimer的实现参考赵大神的文章《一个简单的性能计数器:CodeTimer》:
测试方法如下:
代码如下
复制代码
[Test]
public void TestReflector()
{
CodeTimer.Time("Direct", 100 * 10000,
() =
{
var instance = new ConnectionTest();
});
CodeTimer.Time("Reflect", 100 * 10000,
() =
{
this.GetType().Assembly.CreateInstance("TestPropertyGrid.ConnectionTest");
});
}
测试结果如下:
Direct
Time Elapsed: 25ms
CPU Cycles: 57,582,163
Gen 0: 14
Gen 1: 0
Reflect
Time Elapsed: 3,231ms
CPU Cycles: 8,001,720,795
Gen 0: 269
Gen 1: 1
看到没,我们的放大镜起作用了,现在我们大概可以下这么一个结论:在执行100万遍的时候,反射大概把直接调用慢50~100倍。100倍,咋一看,是相差很大的,但是,我前文说了,别着急下结论,你要看看前提条件。自古我们就喜欢断章取义,比如“以德报怨”这个成语,好像古人说让我们遇到不好的,你不能怨恨,要更好的对待他人,别人打你左脸一巴掌,你应该把右脸伸过去让他再打一下。但实际这个成语是怎样的呢?
或曰:“以德报怨,何如?”
子曰:“何以报德?以直报怨,以德报德”
老孔的意思其实是如果别人对你好,那么你就对他好,要是他招你惹你了,你就干他娘的!你看,傻眼了吧?
有多少情况下需要考虑反射带来的影响?
我认为这个情况是非常非常少的,绝大多数的我们根本就无需考虑这个。就上我上一篇文章提到的工厂,你程序有多少个实体,有100万个吗?如果你只是在弹出窗口的时候new一下,这个百万分之十秒的影响对你很重要吗?
另外,有些人讲,我要是真有这种需求,要把一个对象new一百万遍,那不还是慢吗?这种情况有没有,有!比如我有100w条记录,需要取出来,然后通过反射赋值到一个Model类中。
但是对于这种情况,如果你真是这么想的话,我只能说,你坐办公室坐久了,脑袋生锈了,该去爬爬山,泡泡妞了。如果你需要对一个对象反射一百万遍,那么你就应该缓存这个对象了。拿我们上面那个例子来说,如果这个快递员给小区的人送一百万遍的快递还认不得路,每次都还得百度地图,然后问物业管理,你丫的你还没把他开掉了,那你脑袋不是秀逗了,要不就是任性的有钱人。
上面代码如果缓存之后执行一百万遍,跟直接调用有多大的区别?我这里就不贴代码了,免得你们直接看结果没有意思,自己把代码敲一遍,印象更深刻。
那么,还有没有更快的办法,有。比如你的快递员开始用的是IPHONE4,现在可以考虑给他买个6+。在.net中,提供了Emit的相关方法来让你更快的反射。这里送你一个通过反射快速给Model赋值的轮子“Dapper”,自己回家造去。
编程中是否应该使用反射?
其实看完上面的文字,我相信你们都有了一个初步的判断,而我的看法是:绝大多数的情况下你都可以用反射。
如果你觉得是因为反射导致你程序慢的话,那么,请先用放慢镜好好观察一下,到底是不是反射的问题。如果你确定是反射的问题,那么你再好好的考虑下是不是你没有用对反射,是不是像上面那个走了一百万遍都不认识路的快递员一样。最后,如果你觉得性能上还是不够,那么我建议你升级下硬件吧,把硬件性能上升个3%总好过你请个牛逼的工程师来帮你做这种极限的优化,有一句话我觉得很对“工程师比服务器要昂贵的多”。如果你还非得跟我较劲,那么,没办法了,你程序对性能的要求已经超出了本文讨论的范畴,如果你真有这种需求了,我觉得你也没有必要看我这篇文章了,因为你已经足够牛逼到对系统语言都有深入了解了。
大多时候,我们会把程序的性能归结于编程语言,或者使用了反射等技术,而甚少去关心自己的代码,这种心态会导致你技术的发展越来越缓慢,因为你已经失去了求知的欲望,以及一颗追求技术进步的心。请你记住,更多的时候,影响我们程序性能的,是你编程的思想,你对待编码的态度!
总结
好吧,说了这么多,估计很多人直接就拖到文章末尾然后因为文章码了这么多字而默默点了个赞,那么,我在最后给大家奉献一下本文的精华:
反射大概比直接调用慢50~100倍,但是需要你在执行100万遍的时候才会有所感觉
判断一个函数的性能,你需要把这个函数执行100万遍甚至1000万遍
如果你只是偶尔调用一下反射,请忘记反射带来的性能影响
如果你需要大量调用反射,请考虑缓存。
你的编程的思想才是限制你程序性能的最主要的因素
java反射的性能为什么低
java反射需要将内存中的对象进行解析,涉及到与底层c语言的交互,速度会比较慢。
java反射得到的每一个Method都有一个root,不暴漏给外部,而是每次copy一个Method。具体的反射调用逻辑是委托给MethodAccessor的,而accessor对象会在第一次invoke的时候才创建,是一种lazy init方式。而且默认Class类会cache method对象。目前MethodAccessor的实现有两种,通过设置inflation,一个native方式,一种生成java bytecode方式。native方式启动快,但运行时间长了不如java方式,个人感觉应该是java方式运行长了,jit compiler可以进行优化。所以JDK6的实现,在native方式中,有一个计数器,当调用次数达到阀值,就会转为使用java方式。默认值是15。java方式的实现,基本和非反射方式相同。
Java 反射到底慢在哪里?
其实慢的原因还有安全检查,访问控制等。比如说这个方法你能不能获得,能不能执行等,你传进的参数的类型检查等。
比如说在使用反射调用方法的时候,传进的参数需要检查是否符合方法参数类型要求吧?
可以通过缓存一些方法来提高速度和性能
什么是反射?什么Java反射?
java反射是什么意思呢?下面带大家了解一下。
JAVA反射是指程序可以访问、检测和修改它本身状态或行为的一种能力。反射是一种强大的工具,能够创建灵活的代码,可以使代码在运行时装配,无需在组件之间进行源代表链接。
JAVA反射机制是在运行状态中,知道所有属性和方法,对于任意一个对象,能够调用它的方法和属性,这种动态获取的信息以及动态调用对象的方法的功能的反射机制。
反射适合用在哪
首先我们先思考一个问题,反射适合使用在哪里呢?从功能上看,反射似乎无所不能,几乎所有的类,所有的属性、方法、构造我们都能使用,但是我们细细思考一下,在实际开发中,并不是所有场景都需要使用反射获取属性或者方法进行操作,反而更多的使用实例.xxx方式操作,而当这些操作重复次数较多的时候,我们往往会考虑优化代码,减少代码冗余,提高复用,比如实体构建赋值等操作,这个时候往往是我们最需要复用的地方,所以我们可以大体认为反射主要使用在实体操作过程中。而在一般操作数据的过程中,我们的实体一般都是知道并且依赖于对应的数据类型的,比如:
1.根据类型new的方式创建对象
2.根据类型定义变量,类型可能是基本类型也可能是引用类型、类或者接口
3.将对应类型的对象传递给方法
4.根据类型访问对象的属性,调用方法等操作
以上这些操作都是数据操作的过程中最常见也是最难复用优化的地方,而如果这里的操作使用反射则可以实现动态的操作不同的类型的实例,通过调用反射入口类Class,获取对应的属性、构造、方法完成对应的操作
java课程分享Java的反射机制
Java反射机制是一个非常强大的功能,在很多大型项目比如Spring,Mybatis都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。下面java课程就从实际应用的角度出发,来应用一下Java的反射机制。
反射基础
p.s:本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的QuickStart。
在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类。
通过getClass方法
在Java中,每一个Object都有一个getClass方法,通过getClass方法我们可以获取到这个对象对应的反射类:
Strings="ziwenxie";
Class?c=s.getClass();
通过forName方法
我们也可以调用Class类的静态方法forName:
Class?c=Class.forName("java.lang.String");
使用.class
或者我们也可以直接使用.class:
Class?c=String.class;
获取类型信息
在文章开头我们就提到反射的一大好处就是可以允许我们在运行期间获取对象的类型信息,下面我们通过一个例子来具体看一下。
首先我们在typeinfo.interfacea包下面新建一个接口A:
packagetypeinfo.interfacea;
publicinterfaceA{voidf();}
接着我们在typeinfo.packageaccess包下面新建一个接口C,接口C继承自接口A,并且我们还另外创建了几个用于测试的方法,注意下面几个方法的权限都是不同的。
Java 方法反射机制
确保ation的值和方法名字一样哈
this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class).invoke(this, request, response)就行了哈。
注意你的方法参数 request和response的顺序哈。。要一致哈。。跟这里一样
request在前面 response在后面
java反射优化的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于jdk对反射的优化、java反射优化的信息别忘了在本站进行查找喔。
发布于:2022-12-21,除非注明,否则均为
原创文章,转载请注明出处。