自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

反射是否真的會(huì)讓你的程序性能降低?

開(kāi)發(fā) 開(kāi)發(fā)工具 后端
本來(lái)我覺(jué)得這個(gè)話(huà)題沒(méi)有什么好討論的了,網(wǎng)上已經(jīng)有太多太多的文章在說(shuō)這個(gè)問(wèn)題,有疑問(wèn)的大可以到網(wǎng)上找相關(guān)的文章來(lái)查閱。但是,我想起來(lái)我剛編程的時(shí)候,也是遇到這種困惑到網(wǎng)上一查找,從各種角度闡述的都有,本質(zhì)基本都說(shuō)出來(lái)了,但是還是有很多人不理解,我這里就從我的角度再說(shuō)一遍。

早兩天寫(xiě)了《從把三千行代碼重構(gòu)成15行代碼談起》這篇文章,看到評(píng)論中有一些同學(xué)的回復(fù)還是在質(zhì)疑反射的性能,好像程序用上了反射,就像開(kāi)上了拖拉機(jī)似的。本來(lái)我覺(jué)得這個(gè)話(huà)題沒(méi)有什么好討論的了,網(wǎng)上已經(jīng)有太多太多的文章在說(shuō)這個(gè)問(wèn)題,有疑問(wèn)的大可以到網(wǎng)上找相關(guān)的文章來(lái)查閱。但是,我想起來(lái)我剛編程的時(shí)候,也是遇到這種困惑到網(wǎng)上一查找,從各種角度闡述的都有,本質(zhì)基本都說(shuō)出來(lái)了,但是還是有很多人不理解,我這里就從我的角度再說(shuō)一遍。

[[124971]]

反射肯定比直接調(diào)用慢

這個(gè)毋庸置疑了,我這篇文章也不是證明反射有多高效的。

現(xiàn)在的快遞哥很火,那我們就舉個(gè)快遞的例子。如果快遞員就在你住的小區(qū),那么你報(bào)一個(gè)地址:xx棟xx號(hào),那么快遞員就可以馬上知道你在哪里,直接就去到你家門(mén)口;但是,如果快遞員是***次來(lái)你們這里,他是不是首先得查查百度地圖,看看怎么開(kāi)車(chē)過(guò)去,然后到了小區(qū)是不是得先問(wèn)問(wèn)物管xx棟怎么找,然后,有可能轉(zhuǎn)在樓下轉(zhuǎn)了兩個(gè)圈才到了你的門(mén)前。

我們看上面這個(gè)場(chǎng)景,如果快遞員不熟悉你的小區(qū),是不是會(huì)慢點(diǎn),他的時(shí)間主要花費(fèi)在了查找百度地圖,詢(xún)問(wèn)物業(yè)管理。OK,反射也是一樣,因?yàn)槲沂孪仁裁炊疾恢?,所以我得花時(shí)間查詢(xún)一些其他資料,然后我才能找到你。大家有興趣可以查看反射的實(shí)現(xiàn)原理,以及MetaData的相關(guān)概念。

反射到底比直接調(diào)用慢多少?

好了,我們知道反射肯定慢的,那么是不是反射就不能用了呢?有些人一聽(tīng)到慢,就非常著急的下結(jié)論,反射怎樣怎樣不行,怎樣怎樣不能用。但是,同學(xué),反射到底比直接調(diào)用慢多少,你造嗎,能給我個(gè)實(shí)際的數(shù)據(jù)嗎?很多人其實(shí)對(duì)性能只有個(gè)模糊的概念,而沒(méi)有數(shù)值支撐。之前我給同事找了一個(gè)動(dòng)態(tài)解析表達(dá)式的類(lèi)庫(kù),他覺(jué)得不太好用,他很聰明,很快的找到了用DataTale.Compute可以實(shí)現(xiàn)公式的動(dòng)態(tài)解析。我問(wèn)他,這個(gè)方法和我給的類(lèi)庫(kù)性能上有什么區(qū)別?他跟我說(shuō),這個(gè)已經(jīng)很快了,執(zhí)行1秒都不到。我一聽(tīng),就覺(jué)得不對(duì)勁,你的思想還停留在秒級(jí),跟我談什么性能?

怎么去判斷一個(gè)函數(shù)的性能?因?yàn)楹瘮?shù)的執(zhí)行太快太快了,你需要一個(gè)放慢鏡,這樣才能捕捉到他的速度。怎么做?把一個(gè)函數(shù)執(zhí)行一百萬(wàn)遍或者一千萬(wàn)遍,你才能真正了解一個(gè)函數(shù)的性能。也就是,你如果想判斷性能,你就不能還停留在秒級(jí),毫秒級(jí)的概念,你必須用另外一個(gè)概念替代,才能知道真正的性能。結(jié)果我同事把這兩種方法執(zhí)行了100w遍,確實(shí),我提供的類(lèi)庫(kù)比他的快了8秒。

好了,現(xiàn)在拿我早兩天提供的工廠方法來(lái)做測(cè)試,其中CodeTimer的實(shí)現(xiàn)參考趙大神的文章《一個(gè)簡(jiǎn)單的性能計(jì)數(shù)器:CodeTimer》:

測(cè)試方法如下:

  1. [Test]
  2. public void TestReflector()
  3. {
  4. CodeTimer.Time("Direct", 100 * 10000,
  5. () =>
  6. {
  7. var instance = new ConnectionTest();
  8. });
  9.  
  10. CodeTimer.Time("Reflect", 100 * 10000,
  11. () =>
  12. {
  13. this.GetType().Assembly.CreateInstance("TestPropertyGrid.ConnectionTest");
  14. });
  15. }

測(cè)試結(jié)果如下:

  1. Direct
  2. Time Elapsed: 25ms
  3. CPU Cycles: 57,582,163
  4. Gen 0: 14
  5. Gen 1: 0
  6.  
  7. Reflect
  8. Time Elapsed: 3,231ms
  9. CPU Cycles: 8,001,720,795
  10. Gen 0: 269
  11. Gen 1: 1

看到?jīng)],我們的放大鏡起作用了,現(xiàn)在我們大概可以下這么一個(gè)結(jié)論:在執(zhí)行100萬(wàn)遍的時(shí)候,反射大概把直接調(diào)用慢50~100倍。100倍,咋一看,是相差很大的,但是,我前文說(shuō)了,別著急下結(jié)論,你要看看前提條件。自古我們就喜歡斷章取義,比如“以德報(bào)怨”這個(gè)成語(yǔ),好像古人說(shuō)讓我們遇到不好的,你不能怨恨,要更好的對(duì)待他人,別人打你左臉一巴掌,你應(yīng)該把右臉伸過(guò)去讓他再打一下。但實(shí)際這個(gè)成語(yǔ)是怎樣的呢?

或曰:“以德報(bào)怨,何如?”
子曰:“何以報(bào)德?以直報(bào)怨,以德報(bào)德”

老孔的意思其實(shí)是如果別人對(duì)你好,那么你就對(duì)他好,要是他招你惹你了,你就干他娘的!你看,傻眼了吧?

有多少情況下需要考慮反射帶來(lái)的影響?

我認(rèn)為這個(gè)情況是非常非常少的,絕大多數(shù)的我們根本就無(wú)需考慮這個(gè)。就上我上一篇文章提到的工廠,你程序有多少個(gè)實(shí)體,有100萬(wàn)個(gè)嗎?如果你只是在彈出窗口的時(shí)候new一下,這個(gè)百萬(wàn)分之十秒的影響對(duì)你很重要嗎?

另外,有些人講,我要是真有這種需求,要把一個(gè)對(duì)象new一百萬(wàn)遍,那不還是慢嗎?這種情況有沒(méi)有,有!比如我有100w條記錄,需要取出來(lái),然后通過(guò)反射賦值到一個(gè)Model類(lèi)中。

但是對(duì)于這種情況,如果你真是這么想的話(huà),我只能說(shuō),你坐辦公室坐久了,腦袋生銹了,該去爬爬山,泡泡妞了。如果你需要對(duì)一個(gè)對(duì)象反射一百萬(wàn)遍,那么你就應(yīng)該緩存這個(gè)對(duì)象了。拿我們上面那個(gè)例子來(lái)說(shuō),如果這個(gè)快遞員給小區(qū)的人送一百萬(wàn)遍的快遞還認(rèn)不得路,每次都還得百度地圖,然后問(wèn)物業(yè)管理,你丫的你還沒(méi)把他開(kāi)掉了,那你腦袋不是秀逗了,要不就是任性的有錢(qián)人。

上面代碼如果緩存之后執(zhí)行一百萬(wàn)遍,跟直接調(diào)用有多大的區(qū)別?我這里就不貼代碼了,免得你們直接看結(jié)果沒(méi)有意思,自己把代碼敲一遍,印象更深刻。

那么,還有沒(méi)有更快的辦法,有。比如你的快遞員開(kāi)始用的是IPHONE4,現(xiàn)在可以考慮給他買(mǎi)個(gè)6+。在.net中,提供了Emit的相關(guān)方法來(lái)讓你更快的反射。這里送你一個(gè)通過(guò)反射快速給Model賦值的輪子“Dapper”,自己回家造去。

編程中是否應(yīng)該使用反射?

其實(shí)看完上面的文字,我相信你們都有了一個(gè)初步的判斷,而我的看法是:絕大多數(shù)的情況下你都可以用反射。

如果你覺(jué)得是因?yàn)榉瓷鋵?dǎo)致你程序慢的話(huà),那么,請(qǐng)先用放慢鏡好好觀察一下,到底是不是反射的問(wèn)題。如果你確定是反射的問(wèn)題,那么你再好好的考慮下是不是你沒(méi)有用對(duì)反射,是不是像上面那個(gè)走了一百萬(wàn)遍都不認(rèn)識(shí)路的快遞員一樣。***,如果你覺(jué)得性能上還是不夠,那么我建議你升級(jí)下硬件吧,把硬件性能上升個(gè)3%總好過(guò)你請(qǐng)個(gè)牛逼的工程師來(lái)幫你做這種極限的優(yōu)化,有一句話(huà)我覺(jué)得很對(duì)“工程師比服務(wù)器要昂貴的多”。如果你還非得跟我較勁,那么,沒(méi)辦法了,你程序?qū)π阅艿囊笠呀?jīng)超出了本文討論的范疇,如果你真有這種需求了,我覺(jué)得你也沒(méi)有必要看我這篇文章了,因?yàn)槟阋呀?jīng)足夠牛逼到對(duì)系統(tǒng)語(yǔ)言都有深入了解了。

大多時(shí)候,我們會(huì)把程序的性能歸結(jié)于編程語(yǔ)言,或者使用了反射等技術(shù),而甚少去關(guān)心自己的代碼,這種心態(tài)會(huì)導(dǎo)致你技術(shù)的發(fā)展越來(lái)越緩慢,因?yàn)槟阋呀?jīng)失去了求知的欲望,以及一顆追求技術(shù)進(jìn)步的心。請(qǐng)你記住,更多的時(shí)候,影響我們程序性能的,是你編程的思想,你對(duì)待編碼的態(tài)度!

總結(jié)

好吧,說(shuō)了這么多,估計(jì)很多人直接就拖到文章末尾然后因?yàn)槲恼麓a了這么多字而默默點(diǎn)了個(gè)贊,那么,我在***給大家奉獻(xiàn)一下本文的精華:

  1. 反射大概比直接調(diào)用慢50~100倍,但是需要你在執(zhí)行100萬(wàn)遍的時(shí)候才會(huì)有所感覺(jué)
  2. 判斷一個(gè)函數(shù)的性能,你需要把這個(gè)函數(shù)執(zhí)行100萬(wàn)遍甚至1000萬(wàn)遍
  3. 如果你只是偶爾調(diào)用一下反射,請(qǐng)忘記反射帶來(lái)的性能影響
  4. 如果你需要大量調(diào)用反射,請(qǐng)考慮緩存。
  5. 你的編程的思想才是限制你程序性能的最主要的因素

本文出自:http://www.cnblogs.com/marvin/p/ShallWeUseReflect.html

責(zé)任編輯:林師授 來(lái)源: 博客園
相關(guān)推薦

2015-07-10 09:28:09

事務(wù)性能

2023-11-01 13:48:00

反射java

2010-08-10 13:58:00

Flex性能測(cè)試

2022-05-05 11:21:00

程序優(yōu)化

2025-03-31 08:57:25

Go程序性能

2010-06-11 10:19:22

systemd

2019-02-01 09:50:00

提升Python程序性能

2010-02-04 09:41:03

Android應(yīng)用程序

2013-04-01 09:17:12

ARM通用計(jì)算性能

2009-11-19 08:46:16

Windows 7系統(tǒng)驅(qū)動(dòng)

2023-06-13 13:52:00

Java 7線(xiàn)程池

2018-07-06 16:26:11

編程語(yǔ)言Python程序性能

2010-11-15 16:20:33

Oracle系統(tǒng)優(yōu)化

2024-05-16 11:04:06

C#異步編程編程

2022-10-08 13:13:14

Python程序性能

2011-09-20 10:41:45

Web

2020-12-29 15:00:46

PerfVTune工具

2024-04-29 08:16:18

2009-07-01 18:24:59

JSP應(yīng)用程序JMeter

2018-11-20 10:50:00

Java性能優(yōu)化編程技巧
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)