목차
回复内容:
백엔드 개발 PHP 튜토리얼 语言的反射为什么比较慢,反射存在的意义是什么?为什么C++没有反射?

语言的反射为什么比较慢,反射存在的意义是什么?为什么C++没有反射?

Jun 17, 2016 am 08:31 AM
java php

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用 然后我就不服了 于是我自己撸了套控件出来 直接绑字段(其实大体上就是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),反射的性能消耗是可以忽略不计的。

最后再说一句老生常谈的话 : 不要过早考虑优化(和性能问题),因为不把整个系统做出来的时候你猜测的性能瓶颈经常是不是真实系统的性能瓶颈。 你听没听过数据驱动
用反射会愉快很多 语言的反射为什么比较慢,反射本就是多加入的一块东西,加上之后肯定比没加之前慢(至少不会更快,如果没用到的话)。

反射是一种编程手段,有反射的语言内置了这种能力而已,无反射的语言一般可以自行实现反射。
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). Apr 03, 2025 am 12:04 AM

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? Apr 03, 2025 am 12:03 AM

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

매치 표현식 (PHP 8)과 스위치와 어떻게 다른지 설명하십시오. 매치 표현식 (PHP 8)과 스위치와 어떻게 다른지 설명하십시오. Apr 06, 2025 am 12:03 AM

PHP8에서 매치 표현식은 표현식의 값에 따라 다른 결과를 반환하는 새로운 제어 구조입니다. 1) 스위치 명령문과 유사하지만 실행 명령문 블록 대신 값을 반환합니다. 2) 경기 표현식은 엄격하게 비교되어 (===) 보안을 향상시킵니다. 3) 스위치 명세서에서 가능한 파손을 피하고 코드의 단순성과 가독성을 향상시킵니다.

캡슐의 양을 찾기위한 Java 프로그램 캡슐의 양을 찾기위한 Java 프로그램 Feb 07, 2025 am 11:37 AM

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

See all articles