.NET程序優化不要僅僅盯著代碼執行時間

2020-12-23 IT168

  【IT168 技術】其實很多寫.NET程序的開發人員都很喜歡通過一些計時器來看來一程序或代碼的運行效率,的確這樣是可以計算出代碼執行所損耗的時間。但.net程序的優化不僅僅在於此.大家知道.net提供自動內存回收機制,讓我們不用煩惱內存回收問題;同樣.net提供給我們的內存分配機制也很出色,因為它能非常快速地幫我們進行內存分配工作。當我們在享受吃糖的樂趣的時候,別忘了這東西吃多了很容易把牙齒給搞壞的;同樣.net 回收內存的時候同樣也讓難受,當然這些情況不會在你資源充足的時候給你帶來煩惱;不過一但出現他足可以讓你吃不下飯。

  所以優化.net程序的時候不要忘了GC這東西,解決他的辦法只有一個就是分析那裡產生內存,想盡辦法去產生內存的地方給幹了(說得有點粗爆).前段時間了解了一個對象序列化組件,測試了一下性能發現其效率真的很出色。測試代碼如下:

  int count = 100000;

  KJFObject kobj
= new KJFObject();

  kobj.Mm
= new int[] { 34, 24, 545 };

  kobj.Haha
= "asfsfasfasfas";

  kobj.Bind();

  System.Diagnostics.Stopwatch sw
= new System.Diagnostics.Stopwatch();

  sw.Start();

  
for (int i = 0; i < count; i++)

  {

  kobj
= new KJFObject();

  kobj.Mm
= new int[] { 34, 24, 545 };

  kobj.Haha
= "asfsafsafsafasdfasfasf";

  kobj.Bind();

  }

  sw.Stop();

  Console.WriteLine(sw.Elapsed.TotalMilliseconds);

  BufferWriter writer
= new BufferWriter(Encoding.UTF8);

  sw.Reset();

  sw.Start();

  
for (int i = 0; i < count; i++)

  {

  BObject bobj
= new BObject();

  bobj.Mm
= new int[] { 34, 24, 545 };

  bobj.Haha
= "asfsafsafsafasdfasfasf";

  writer.Reset();

  bobj.Save(writer);

  }

  Console.WriteLine(sw.Elapsed.TotalMilliseconds);

${PageNumber}

  他的序列化效率比直接代碼方式效率只低了50%,這50%的差距帶的效果就是編寫對象的時候更靈光和代碼更少,這是完全可取的。其實測試結果是偏向於後者,如果細心的朋友一定發現一個問題,BufferWriter是可復用的;如果沒有這種機制的情況那後者是完全輸給前者的。以下是兩個實體的定義:

  public class KJFObject: IntellectObject

  {

  
private int[] _mm;

  [IntellectProperty(
0)]

  
public int[] Mm

  {

  
get { return _mm; }

  
set { _mm = value; }

  }

  
private string _haha;

  [IntellectProperty(
1)]

  
public string Haha

  {

  
get { return _haha; }

  
set { _haha = value; }

  }

  }

  
public class BObject:IMessage

  {

  
private int[] _mm;

  
public int[] Mm

  {

  
get { return _mm; }

  
set { _mm = value; }

  }

  
private string _haha;

  
public string Haha

  {

  
get { return _haha; }

  
set { _haha = value; }

  }

  
public void Load(BufferReader reader)

  {

  Mm
= reader.ReadInt32s();

  Haha
= reader.ReadString();

  }

  
public void Save(BufferWriter writer)

  {

  writer.Write(Mm);

  writer.Write(Haha);

  }

  }

  如果緊緊是這樣效率上的差異,那必然不會選擇手寫代碼來做,因為手寫代碼不好維護,容易出錯特別是在大量成員讀寫順序上.從效率上來說這個組件可以說是完全勝任。當我在做下一步測試的時候發現組件的問題,就是沒有內存復用機制;於是用內存分析工具分析一下內存使用狀況。發現其內存使用情況有點差,內存的開銷有點大,在大並發下其GC壓力估計不少。以下是一個測結果:

 

  從測試結果來看排在前頭的有Enumerator,這東西是怎產生的呢,其實就是我們習慣用Foreach產生的,從執行效率上來說Foreach和for沒多大差異,差別就在內存分配和回收上。當然你能通過用for把這個對象的開銷幹了,能就更好的事情.byte[] char[]這些都可以通過復用的給幹了,這樣大頭內存開銷基本就沒有了。

  那手寫代碼控制序列化同樣的工作其內存使用又怎樣呢?

  從內存使用結果來看其差距還是非常大的,足足有5-6倍的差異,這些內存的GC回來在高並發下足可以讓整體處理性能最少有著10%的提升。所以內存復用在.net程序優化中起著十分重要的作用,只是這種優化能體現出來的場景有限;不過當你的產品面對運營的時候發現那就是件比較麻煩的事情,因為這些調整很有可能影響一些核心的地方。當你面對高性能應用的時候別忘了GC這個傢伙,它真是一個要命的東西。

相關焦點

  • VBA 代碼程序運行時間的優化與視覺效果的兼顧
    程序的編寫過程中,在第二冊的85講到89講,我講了程序優化的問題,其實在這些章節中,我也一直在講視覺和程序運行時間的兼顧問題。我在做程序的時候,往往注重的是前者,而不是後者,為什麼呢?其實VBA帶給我們的就是實用,真正要求做到節約時間往往是那些大型程序考慮的範疇,正如我在講到VBA地位時的比喻,那些大型程序是城市與城市之間的高鐵啊、火車啊、飛機啊,而VBA只是連接車站到家之間的汽車、電動車,當你考慮大型數據處理時最好要藉助大型程序,如Python、PHP、GO、JAVA等等,從嚴格意義上講,VBA不能稱之為一種獨立的語言體系,只是寄生於OFFICE的一條寄生蟲,但你不要小看它,這部分交通運行不順暢
  • 嵌入式Linux啟動時間優化的秘密之一工具鏈/應用程式優化
    1.降低啟動時間的一般思路   在準備降低系統的啟動時間時,思路上應建立以下的切入點:   最快的代碼是未執行的代碼。   引導操作本質上的很大一部分工作實際上是將代碼和數據從存儲設備加載到RAM。如所需加載內容越少則意味著加載操作越快。   如果根文件系統越大,則安裝時間可能會越長。
  • 不要忽略代碼執行的錯誤
    老規矩,先分享書裡這個章節的大意,再寫「命題作文」 不處理程序的錯誤會導致脆弱的、不安全的甚至無法維護的代碼。 https://97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_26/個人簡評:它講了一個非常普通的道理——小錯不改會鑄成大錯。
  • 編寫高效的C程序與C代碼優化
    雖然對於優化C代碼有很多有效的指導方針,但是對於徹底地了解編譯器和你工作的機器依然無法取代,通常,加快程序的速度也會加大代碼量。這些增加的代碼也會影響一個程序的複雜度和可讀性,這是不可接受的,比如你在一些小型的設備上編程,例如:行動裝置、PDA……,這些有著嚴格的內存限制,於是,在優化的座右銘是:寫代碼在內存和速度都應該優化。
  • 代碼中經常使用With,也能讓你的VBA程序優化恰到好處
    其實,優化代碼有多種方法,有的可以個人根據自己的經驗去總結,比如:在需要重複引用同一個對象時可以使用With語句來獲得較快的運行速度.With語句,在一個單一對象或一個用戶定義類型上執行一系列的語句。Statements為要執行在object上的一條或多條語句。為什麼採用with語句會節約時間呢?我個人的理解,在使用WITH語句時,計算機會預讀object入內存,之後只是內存的調用,不必再反覆的讀取了。或者說With語句可以對某個對象執行一系列的語句,而不用重複指出對象的名稱。
  • ABAP程序效率優化系列之②——開發優化之ABAP時間
    ABAP程序效率優化系列文章歷史ABAP程序效率優化系列之①——業務層面的優化開發層面的優化內容太多,但目的只有一個
  • 嵌入式平臺ARM的C代碼優化方法
    本文介紹了ARM平臺的C代碼優化方法,從數據類型選擇、數據結構組織、局部變量選擇、函數inline內聯、編譯器選項、循環展開、條件執行、數據操作的轉化、存儲器的優化、代碼尺寸的優化等角度給出常用的優化方法。
  • MXNet設計筆記之:深度學習的編程模式比較
    命令式程序按照我們的命令來執行運算過程。大多數Python代碼都屬於命令式,例如下面這段numpy的計算。import numpy as npa = np.ones(10)b = np.ones(10) * 2c = b * ad = c + 1當程序執行到 c = b * a 這一行時,機器確實做了一次乘法運算。
  • 代碼執行、命令執行漏洞-PHP
    ,'~','<','>','^','(',')','[',']','{','}','$','\','\x0A','\xFF','%',' ' ',' " '               //僅僅在不成對時被轉義                     <?
  • PHP的語言層面的優化以及代碼優化技巧
    首頁 > 語言 > 關鍵詞 > php最新資訊 > 正文 PHP的語言層面的優化以及代碼優化技巧
  • .net framework 4.0 64位下載|.net framework 4.0 64位官方下載...
    .net framework 4.0 64位是很多軟體和遊戲都需要的運行庫、支持win7 64位系統旗艦版,很多時間的表現為,點擊啟動程序exe沒有反應,這很可能就是.net framework 4.0沒有裝好了,是支持win7系列的64位可用的版本,就是64位系統下點擊exe沒有反應所需要的運行庫。
  • 小白福利/Pandas代碼快速優化攻略
    今天,大狗要說的是關於Pandas的代碼優化問題,Pandas 是Python Data Analysis Library的簡寫,它是為了解決數據分析任務而創建的工具,所以今天得文章大狗一共介紹了五種效率優化的方法來供大家參考。
  • 嵌入式C語言優化你不能不知道的技巧……
    開發人員應注意嵌入式 C語言和標準 C 語言的區別,減少生成代碼長度,提高程序執行效率,在程序設計中對代碼進行優化。現在的 C 編譯器會自動對代碼進行優化,但這些優化是對執行速度和代碼長度的平衡。如果要獲得更小且執行效率更高的代碼,需要程式設計師手工對代碼進行優化。
  • CPU 執行程序的秘密
    3、運算單元用於執行運算指令;知道了圖靈機的組成後,我們以簡單數學運算的 1 + 2 作為例子,來看看它是怎麼執行這行代碼的。程序編譯過程中,編譯器通過分析代碼,發現 1 和 2 是數據,於是程序運行時,內存會有個專門的區域來存放這些數據,這個區域就是「數據段」。
  • 基於TI C6000系列DSP的C/C++程序優化技術
    在此介紹TI C6000的軟體開發流程,重點討論C6000系列的C/C++程序優化技術,包括優化流程,C/C++代碼優化方法,編寫線形彙編代碼優化方法等。為DSP的C/C++軟體開發提供了全面的程序優化技術和方法,對實際系統的開發具有重要的現實意義。
  • 幾乎是史上最全最實用的Android性能全面分析與優化方案研究
    1、性能優化原則堅持性能測試(開發和測試同學的測試方法略有不同):不要憑感覺去檢測性能問題、評估性能優化的效果,應該保持足夠多的測量,用數據說話(主要針對測試同學)。使用低配置的設備:同樣的程序,在低端配置的設備中,相同的問題會暴露得更為明顯。權衡利弊:在能夠保證產品穩定、按時完成需求的前提下去做優化。
  • 50個技巧提高你的PHP網站程序執行效率
    26、調用帶有一個參數的空函數,其花費的時間相當於執行7至8次的局部變量遞增操作。類似的方法調用所花費的時間接近於15次的局部變量遞增操作。27、Apache解析一個PHP腳本的時間要比解析一個靜態HTML頁面慢2至10倍。儘量多用靜態HTML頁面,少用腳本。28、除非腳本可以緩存,否則每次調用時都會重新編譯一次。
  • 【PC樣本分析】python可執行程序分析
    概述第一次分析這種python exe程序,最開始還比較懵逼,直接對exe就開始下手了,發現它竟然會去釋放並運行python dll,一直沒想明白,結果浪費了不少時間,最後終於找到了正確的分析思路,所以,覺得挺有意思的,就分享給大家看看。樣本很大,有3.16MB,一般的exe程序不會這麼大,所以用了壓縮殼UPX。1.1.
  • 程序丨Unity優化技巧(中):介紹具體的優化方式
    下面列舉部分比較通用的優化方案。LOD,代碼只在必要時才會運行最常用的優化方式。例如屏幕外的角色不計算動畫更新,不計算技能效果冒字血條等,屏幕外的角色休眠,只有主角才會冒字等等。例如軒轅城擂臺,同屏高配200人,未優化在68幀左右優化的後到94幀左右)限幀,負載均衡為了降低耗電發熱量我們會根據玩家機型進行限幀。另一方面我們將邏輯幀和渲染幀分開執行,邏輯代碼以更低的幀率執行,部分邏輯也可以使用線程,負載均衡分段計算等方法提升性能。
  • PointNet代碼解讀
    今天寫點代碼方面的內容,昨天已經簡單講解過paper了,只看文章的話,理解的效果一般,所以今天結合代碼再來充分認識PointNet。代碼分為分類、分割兩部分,本文以分類為例。關於論文的講解,感興趣的可以點這裡。這部分代碼位於pointnet_cls.py中。