语言的反射为什么比较慢,反射存在的意义是什么?为什么C++没有反射?
程序员文章站
2022-06-01 14:28:10
...
1.php,java,C#都有反射,但是很多教程都说反射比较慢,那么反射为什么比较慢?
2.既然他比较慢为什么这些语言都提供反射,反射对于这些语言是必须的吗?
3.为什么C++没有反射,C++也是面向对象的啊
反射慢的情况可能是调用时得做逆优化, 或者是语言和反射 API 的设计蛋疼, 使得反射调用必须增加一些装箱拆箱参数重排异常重抛等等额外工作.
就算同一种语言, 反射快慢也是和实现相关的. 例如运行时对象元数据都保留着, 并且对对象结构基本不做优化, 那反射就和普通方法一样快. 现在的编译期通过改进的程序分析, 也可以把某些反射代码优化成和普通代码一样快的程度吧.
再说"反射" 连 C 都可以做, 例如 __typeof__ 可以编译期获取一个变量的类型, 没有 __typeof__ 一些宏你就是写不出的... 而 dlsym 就可以看成 C 的 "运行时反射". C++ 还可以用模板特化在编译期获取一些类型的信息. 至于什么用, 代码写多了经常想想怎么 Don't Repeat Yourself 就明白了. 最开始学.net的时候我也一直奇怪。。。这货要了干嘛?重点书上举的例子莫名其妙 attribute居然是给代码加注释。。。蛇精病啊(也可能是我到现在都没理解到这一层)
然后我最近在撸MVC(多年webform感觉现在是MVC大潮要跟上潮流) 然后我down了个MVCMusicStore在看 这里头Model层直接给属性加了个[Required]特性。。。然后我就在想 卧槽卧槽卧槽 劳资还在苦逼的在ASPX页面写各种校验呢!
然后的然后 我发现这货只能MVC用 然后我就不服了 于是我自己撸了套控件出来 直接绑字段(其实大体上就是http://asp.net自带的那套控件加了个BindTo属性) ---你看这里就要用反射了吧-----页面的CRUD逻辑全部都不怎么用写了 然后既然有了BindTo属性 那我就可以直接拿到那个[Required]特性了 于是我在页面初始化的时候把每个有BindTo属性的控件循环了一遍 然后看看有没有Required特性 --------你看这里还是反射--------然后组个Dictionary再序列化成Json到前端, 前端写个JS去校验----这里是用到把JS嵌入到dll-----然后我就彻底告别写蛋疼的绑定字段代码和校验代码了
反射这种东西要虚拟机或者运行平台才好处理,像c++这种原生字节,能够提供运行时类型就已近非常不错了。
还有,面向对象是面向对象,反射不属于面向对象的硬指标。
最后说一句,cpp有cpp的写法,反射什么离远点。 我只说说我所理解的编程语言中反射的意义。
你在上班,去了躺茅房回来发现你的桌子上有一张纸条,上面写着“XX领导让你去找他一趟,立刻!”。此时,你一定会马不停蹄的跑去找领导了。
好了。这个场景里,“XX领导让你去找他一趟,立刻!”是一条语句指令,而你“马不停蹄的跑去找领导”就是对这条语句指令的执行。
因为你是人,你是高级动物,你是有自省能力的。也就是说,你在跑去找领导的途中或者之后,你会知道:我是因为看到了纸条上的“XX领导让你去找他一趟,立刻!”我才去的,进一步的,你会知道这是在上班时间,所以领导找你估计是有工作上的事情要问你,等等等等,也就是说:你知道你自己是在干什么。
问题来了:计算机程序在执行完一系列语句指令后,它知道自己执行的是啥么?它知道它自己是在干什么么?反射,就是试图在语言层面提供一种这样的能力:让代码有自省能力,让代码知道自己在干什么,尽管目前的实现还很初级、很浅薄。 有些实现不使用反射,程序写起来不美且不自动。
我看到某些JAVA项目,一个action-mappings配置顶天的时候,
再看看struts最新特性不需要如此配置的时候(有可能举例错了,接触java没多久),我就默默的哭了有没有!
很多地方,使用了反射,可以实现很优雅的实现方式,而且尼玛的只要短短几行代码,知道吗!
应用场景的话,有一个,权限分配。根据模块、控制器、方法为粒度的权限配置。
需要使用到反射来知道有哪些控制器和方法。
当然,我说的是PHP的,而且反射不止这么一点点好处! 比如在数据库里有一张数据表有若干字段,我们代码中有个类,里面有若干成员。
如果我们的需求是把代码中的那个类的实例写入到数据表中时,就存在一个“类的哪个成员的值写入到数据表中的哪个字段”的需求。
这个需求可以不使用反射就能实现,但是笨拙低效,不灵活。如果语言有反射语法,那么实现这个需求就可以做的简洁灵活(写代码效率)高效。
至于反射的性能.......这都不是个事,如果你觉得反射性能不好,那么不使用反射就是了。
在我的实践中,反复测量过一块高频度使用反射的代码块的性能,怎么测那个代码块耗时都是0 -1ms(测量精度也是1ms)。所以起码在我的这个应用场景中(响应一次操作耗时0.6 - 1.2 s),反射的性能消耗是可以忽略不计的。
最后再说一句老生常谈的话 : 不要过早考虑优化(和性能问题),因为不把整个系统做出来的时候你猜测的性能瓶颈经常是不是真实系统的性能瓶颈。 你听没听过数据驱动
用反射会愉快很多 语言的反射为什么比较慢,反射本就是多加入的一块东西,加上之后肯定比没加之前慢(至少不会更快,如果没用到的话)。
反射是一种编程手段,有反射的语言内置了这种能力而已,无反射的语言一般可以自行实现反射。
2.既然他比较慢为什么这些语言都提供反射,反射对于这些语言是必须的吗?
3.为什么C++没有反射,C++也是面向对象的啊
回复内容:
通常不是反射慢, 而是用了反射的代码做不了某些优化...反射慢的情况可能是调用时得做逆优化, 或者是语言和反射 API 的设计蛋疼, 使得反射调用必须增加一些装箱拆箱参数重排异常重抛等等额外工作.
就算同一种语言, 反射快慢也是和实现相关的. 例如运行时对象元数据都保留着, 并且对对象结构基本不做优化, 那反射就和普通方法一样快. 现在的编译期通过改进的程序分析, 也可以把某些反射代码优化成和普通代码一样快的程度吧.
再说"反射" 连 C 都可以做, 例如 __typeof__ 可以编译期获取一个变量的类型, 没有 __typeof__ 一些宏你就是写不出的... 而 dlsym 就可以看成 C 的 "运行时反射". C++ 还可以用模板特化在编译期获取一些类型的信息. 至于什么用, 代码写多了经常想想怎么 Don't Repeat Yourself 就明白了. 最开始学.net的时候我也一直奇怪。。。这货要了干嘛?重点书上举的例子莫名其妙 attribute居然是给代码加注释。。。蛇精病啊(也可能是我到现在都没理解到这一层)
然后我最近在撸MVC(多年webform感觉现在是MVC大潮要跟上潮流) 然后我down了个MVCMusicStore在看 这里头Model层直接给属性加了个[Required]特性。。。然后我就在想 卧槽卧槽卧槽 劳资还在苦逼的在ASPX页面写各种校验呢!
然后的然后 我发现这货只能MVC用 然后我就不服了 于是我自己撸了套控件出来 直接绑字段(其实大体上就是http://asp.net自带的那套控件加了个BindTo属性) ---你看这里就要用反射了吧-----页面的CRUD逻辑全部都不怎么用写了 然后既然有了BindTo属性 那我就可以直接拿到那个[Required]特性了 于是我在页面初始化的时候把每个有BindTo属性的控件循环了一遍 然后看看有没有Required特性 --------你看这里还是反射--------然后组个Dictionary再序列化成Json到前端, 前端写个JS去校验----这里是用到把JS嵌入到dll-----然后我就彻底告别写蛋疼的绑定字段代码和校验代码了
反射比较慢什么的,其实是不对的。你拿他跟谁比较啊,你没有反射就做不了某些事情,所以当你要做某些事情的时候,你就必须用反射。当然了,你做a=b+c这种事情的时候,反射是慢,这就跟interpreting和jit的区别一样嘛。
说来,反射其实具有用的。我www.gaclib.net 用C++,就给造了一套反射,没反射很多declarative programming的方法都没法再imperative programming language上做啊,说白了就是要创造DSL。你又要DSL,又要DSL跟原来的语言的结构能交互是吧,不就是要求你的语言具有一定的动态性,反射在这个时候就有用了……
至于C++嘛,这是他爹的口味问题。
The earliest computers were programmed in their native assembly language, which were inherently reflective as these original architectures could be programmed by defining instructions as data and using self-modifying code. As programming moved to higher-level languages such as C, this reflective ability disappeared (outside of malware) until programming languages with reflection built into their type systems appeared. 这个问题要切身的用javac#做项目的人才知道反射的好处,特别是项目的框架的加载。反射不能一概而论的性能,有的地方反射就很快,某些地方来说性能也不是问题,比如框架模块的加载,一般只会反射然后加载一次,当然热插拔的模块会动态加载。反射这种东西要虚拟机或者运行平台才好处理,像c++这种原生字节,能够提供运行时类型就已近非常不错了。
还有,面向对象是面向对象,反射不属于面向对象的硬指标。
最后说一句,cpp有cpp的写法,反射什么离远点。 我只说说我所理解的编程语言中反射的意义。
你在上班,去了躺茅房回来发现你的桌子上有一张纸条,上面写着“XX领导让你去找他一趟,立刻!”。此时,你一定会马不停蹄的跑去找领导了。
好了。这个场景里,“XX领导让你去找他一趟,立刻!”是一条语句指令,而你“马不停蹄的跑去找领导”就是对这条语句指令的执行。
因为你是人,你是高级动物,你是有自省能力的。也就是说,你在跑去找领导的途中或者之后,你会知道:我是因为看到了纸条上的“XX领导让你去找他一趟,立刻!”我才去的,进一步的,你会知道这是在上班时间,所以领导找你估计是有工作上的事情要问你,等等等等,也就是说:你知道你自己是在干什么。
问题来了:计算机程序在执行完一系列语句指令后,它知道自己执行的是啥么?它知道它自己是在干什么么?反射,就是试图在语言层面提供一种这样的能力:让代码有自省能力,让代码知道自己在干什么,尽管目前的实现还很初级、很浅薄。 有些实现不使用反射,程序写起来不美且不自动。
我看到某些JAVA项目,一个action-mappings配置顶天的时候,
再看看struts最新特性不需要如此配置的时候(有可能举例错了,接触java没多久),我就默默的哭了有没有!
很多地方,使用了反射,可以实现很优雅的实现方式,而且尼玛的只要短短几行代码,知道吗!
应用场景的话,有一个,权限分配。根据模块、控制器、方法为粒度的权限配置。
需要使用到反射来知道有哪些控制器和方法。
当然,我说的是PHP的,而且反射不止这么一点点好处! 比如在数据库里有一张数据表有若干字段,我们代码中有个类,里面有若干成员。
如果我们的需求是把代码中的那个类的实例写入到数据表中时,就存在一个“类的哪个成员的值写入到数据表中的哪个字段”的需求。
这个需求可以不使用反射就能实现,但是笨拙低效,不灵活。如果语言有反射语法,那么实现这个需求就可以做的简洁灵活(写代码效率)高效。
至于反射的性能.......这都不是个事,如果你觉得反射性能不好,那么不使用反射就是了。
在我的实践中,反复测量过一块高频度使用反射的代码块的性能,怎么测那个代码块耗时都是0 -1ms(测量精度也是1ms)。所以起码在我的这个应用场景中(响应一次操作耗时0.6 - 1.2 s),反射的性能消耗是可以忽略不计的。
最后再说一句老生常谈的话 : 不要过早考虑优化(和性能问题),因为不把整个系统做出来的时候你猜测的性能瓶颈经常是不是真实系统的性能瓶颈。 你听没听过数据驱动
用反射会愉快很多 语言的反射为什么比较慢,反射本就是多加入的一块东西,加上之后肯定比没加之前慢(至少不会更快,如果没用到的话)。
反射是一种编程手段,有反射的语言内置了这种能力而已,无反射的语言一般可以自行实现反射。