新聞中心
本文轉(zhuǎn)載自微信公眾號(hào)「JeffckyShare」,作者Jeffcky 。轉(zhuǎn)載本文請(qǐng)聯(lián)系JeffckyShare公眾號(hào)。

成都創(chuàng)新互聯(lián)公司一直秉承“誠(chéng)信做人,踏實(shí)做事”的原則,不欺瞞客戶(hù),是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個(gè)客戶(hù)多一個(gè)朋友!為您提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、成都網(wǎng)頁(yè)設(shè)計(jì)、微信小程序定制開(kāi)發(fā)、成都網(wǎng)站開(kāi)發(fā)、成都網(wǎng)站制作、成都軟件開(kāi)發(fā)、重慶App定制開(kāi)發(fā)是成都本地專(zhuān)業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計(jì)公司,等你一起來(lái)見(jiàn)證!
個(gè)人以為,性能并非一次性就可完全成全,需結(jié)合實(shí)際業(yè)務(wù)有一個(gè)大致評(píng)估或預(yù)期,比如數(shù)據(jù)量大小,若預(yù)期短暫并不會(huì)達(dá)到性能瓶頸,大可不必過(guò)度考慮,又或者根據(jù)自我假想可能存在性能問(wèn)題,于是大張旗鼓陷入自我意識(shí)流,最終可能結(jié)果吃虧反而不討好。
項(xiàng)目性能考慮
此前我個(gè)人寫(xiě)過(guò)一版Excel導(dǎo)入和導(dǎo)出,并未使用對(duì)應(yīng)開(kāi)源組件,因?yàn)閷?dǎo)出和導(dǎo)入邏輯并不復(fù)雜,不涉及單元格拆分、包含圖片、下拉框等等,但處理起來(lái)也并沒(méi)有什么難度,借助NPOI或EPPLUS工具皆可滿足。
于是我嘗試將此前封裝Excel導(dǎo)入和導(dǎo)出做了進(jìn)一步重構(gòu)處理,主要為解決此前遺留問(wèn)題:
其一:表頭列和實(shí)體屬性列順序必須一一對(duì)應(yīng)
其二:導(dǎo)出由于Excel單個(gè)Sheet行有限制,超出一定行,必須重建Sheet
其三:大量使用反射,若存在多個(gè)Sheet,且每個(gè)Sheet行數(shù)量稍微巨大,則存在一定性能瓶頸
如上兩點(diǎn)可以簡(jiǎn)單解決,這里我們忽略,問(wèn)題在于第三點(diǎn),因?yàn)槭褂梅盒?,針?duì)每一行讀取都會(huì)反射對(duì)象,同時(shí)也要獲取其實(shí)例屬性并賦值,這里我們完全可以改善下性能
接下來(lái),我們通過(guò)一個(gè)簡(jiǎn)單例子,來(lái)演示如何改善反射性能,當(dāng)然,也還有其他方案,這里我只介紹我個(gè)人的方案
反射性能改善
如一部分開(kāi)源組件一樣,我們通過(guò)特性標(biāo)識(shí)屬性,屬性名稱(chēng)和表頭列匹配,順序無(wú)需一致,同樣,屬性可忽略賦值
基于上述情況,我們要獲取對(duì)應(yīng)實(shí)體所標(biāo)識(shí)的屬性特性,這里為便于后續(xù)屬性賦值,我們緩存屬性相關(guān)信息,避免頻繁通過(guò)反射獲取屬性信息
接下來(lái),我們來(lái)到屬性賦值和獲取,我們以設(shè)置值為例,獲取值同理,同時(shí)以1萬(wàn)作為基數(shù)來(lái)驗(yàn)證,然后以此基數(shù)遞增,如下測(cè)試實(shí)體
- public class Test
- {
- public int Id { get; set; }
- public string Name { get; set; }
- }
反射屬性賦值示例,如下:
- static void ReflectionExample(int count)
- {
- var stopWatch = new Stopwatch();
- stopWatch.Start();
- var tests = Enumerable.Repeat(new Test(), count).ToList();
- var propertyIdInfo = typeof(Test).GetProperty("Id");
- var propertyNameInfo = typeof(Test).GetProperty("Name");
- foreach (var test in tests)
- {
- propertyIdInfo.SetValue(test, 1);
- propertyNameInfo.SetValue(test, "jeffcky");
- }
- Console.WriteLine($"反射賦值耗時(shí):{stopWatch.ElapsedMilliseconds}ms");
- }
當(dāng)然,根據(jù)筆記本配置以及所使用耗時(shí)方案不標(biāo)準(zhǔn),結(jié)果會(huì)存在差異,但基本可判斷反射耗時(shí)會(huì)有20ms以上
接下來(lái),我使用委托方式來(lái)直接調(diào)用屬性Set方法,看看性能是否會(huì)有改善
- static void DelegateExample(int count)
- {
- var stopWatch = new Stopwatch();
- stopWatch.Start();
- var tests = Enumerable.Repeat(new Test(), count).ToList();
- var setId = (Action
)Delegate.CreateDelegate(typeof(Action ), null, - typeof(Test).GetProperty("Id").GetSetMethod());
- var setName = (Action
)Delegate.CreateDelegate(typeof(Action ), null, - typeof(Test).GetProperty("Name").GetSetMethod());
- foreach (var test in tests)
- {
- setId(test, 3);
- setName(test, "jeffcky");
- }
- Console.WriteLine($"委托賦值耗時(shí):{stopWatch.ElapsedMilliseconds}ms");
- }
接下來(lái),我們對(duì)比反射1萬(wàn)條數(shù)據(jù)屬性賦值,看看耗時(shí)情況怎樣
通過(guò)運(yùn)行多次,通過(guò)調(diào)用委托賦值其耗時(shí)基本可控制在5ms以?xún)?nèi),想想差距還是有點(diǎn)大,接下來(lái)我們將數(shù)據(jù)量直接上升到100萬(wàn)看看其差距
結(jié)果顯而易見(jiàn),通過(guò)反射耗時(shí)將超過(guò)1s,而委托賦值則控制在幾十ms,如果再加上屬性的個(gè)數(shù)和獲取屬性值,耗時(shí)時(shí)間勢(shì)必將會(huì)再一次拉大
為何很多人都說(shuō)反射性能很差,因?yàn)橐敕瓷鋾?huì)通過(guò)如下幾步對(duì)性能有巨大損耗
其一:檢查所調(diào)用方法是否存在
其二:檢查其安全性和訪問(wèn)可見(jiàn)性
其三:檢查簽名,確保所提供的參數(shù)和類(lèi)型的數(shù)量與方法定義簽名一致
其四:解出參數(shù)
此文意非強(qiáng)調(diào)不能用反射,網(wǎng)上討論也很多,還是老話,根據(jù)實(shí)際業(yè)務(wù)情況,具體分析,別整體就惦記和揪著性能不放,比如針對(duì)快遞行業(yè),導(dǎo)入和導(dǎo)出操作可謂再正常不過(guò),其導(dǎo)入數(shù)量也是龐大,對(duì)于此種情況,我們是否可考慮通過(guò)結(jié)構(gòu)體存儲(chǔ)數(shù)據(jù)呢?一切皆通過(guò)實(shí)際場(chǎng)景出發(fā)。
那么問(wèn)題來(lái)了,寫(xiě)本文的目的是什么呢?
本文題目:什么時(shí)候我們應(yīng)談及性能?
URL鏈接:http://m.fisionsoft.com.cn/article/ccoohdg.html


咨詢(xún)
建站咨詢(xún)
