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-----然後我就徹底告別寫蛋疼的綁定欄位代碼和校正代碼了
反射比較慢什麼的,其實是不對的。你拿他跟誰比較啊,你沒有反射就做不了某些事情,所以當你要做某些事情的時候,你就必須用反射。當然了,你做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),反射的效能消耗是可以忽略不計的。
最後再說一句老生常談的話 : 不要過早考慮最佳化(和效能問題),因為不把整個系統做出來的時候你猜測的效能瓶頸經常是不是真實系統的效能瓶頸。你聽沒聽過資料驅動
用反射會愉快很多語言的反射為什麼比較慢,反射本就是多加入的一塊東西,加上之後肯定比沒加之前慢(至少不會更快,如果沒用到的話)。
反射是一種編程手段,有反射的語言內建了這種能力而已,無反射的語言一般可以自行實現反射。