親愛的讀者,在這篇文章中,我提供了一些c#編程的最佳實踐。web
你是否在用戶輸入驗證中使用異常處理機制?
若是是,那麼你就是那個把你的項目執行速度下降了62倍的人。你不相信我嗎?等幾分鐘;我來教你怎麼作。可是在這個例子以前,讓咱們瞭解一下在什麼地方須要異常處理。編程
例如,你正在驗證用戶的數據,對於任何無效的輸入,你將引起一個異常並將其拋出給客戶端,以下所示:c#
class BusinessLogcCheck { public void Check() { try { //Your validation code is here } catch (Exception ex) { throw new Exception("My own exception"); } } }
親愛的朋友,在下一個示例中,若是你看到輸出屏幕,你將意識到這種作法有多糟糕。讓咱們看看下面的代碼。數組
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; namespace Test1 { class Program { public static void ThrowTest() { throw new Exception("This is exceptopn"); } public static Boolean Return() { return false; } static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); try { ThrowTest(); } catch { } sw.Stop(); Console.WriteLine("With Exception " + sw.ElapsedTicks); sw.Restart(); try { Return(); } catch { } sw.Stop(); Console.WriteLine("With Return " + sw.ElapsedTicks); Console.ReadLine(); } } }
這就是你等待的輸出。ide
個人概念證實很是簡單。在一個函數中,我拋出了一個異常,在另外一個函數中,我在檢查用戶輸入後返回一個布爾值。我還附上了一個計算器的屏幕(哈哈..),讓你相信異常處理是如何影響代碼性能的。函數
所以,咱們能夠得出這樣一個結論:「不要爲用戶輸入驗證引起異常。」使用布爾返回技術(或相似的技術)來驗證業務邏輯中的輸入」。由於異常對象的開銷很是大。oop
永遠不要在循環中實現try-Catch
是的,它也與異常處理有關。我重複「永遠不要在循環中執行try-catch」。讓我用一個例子來證實。 性能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; namespace Test1 { class Program { static void Method1() { for (int i = 0; i < 1000; i++) { try { int value = i * 100; if (value == -1) { throw new Exception(); } } catch { } } } static void Method2() { try { for (int i = 0; i < 1000; i++) { int value = i * 100; if (value == -1) { throw new Exception(); } } } catch { } } static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); Method1(); sw.Stop(); Console.WriteLine("Within Loop " + sw.ElapsedTicks); sw.Restart(); Method2(); sw.Stop(); Console.WriteLine("Outside of Loop " + sw.ElapsedTicks); Console.ReadLine(); } } }
這是輸出屏幕。
學習
在method1的這個程序中,我在for循環中實現了異常處理機制,而在method2中,我在沒有循環的狀況下實現了異常處理機制。咱們的輸出窗口代表,若是咱們在for循環外實現try-catch程序的執行速度將比循環內的try-catch快2倍。測試
一樣,惟一的結論是「不要在項目的循環中實現try-catch。(是的!不只在for循環中,並且在任何循環中。)
你是否瘋狂到要使用new操做符來建立一個整數變量?
親愛的讀者,不要由於我寫了這麼長的標題而批評我,也不要使用new操做符來建立一個簡單的整數變量。我知道你會說,若是你使用new操做符建立一個簡單的整數變量就會被自動設置爲0,不遭受錯誤,如「未賦值的局部變量」,但這真的是須要獲得一個自動賦值爲0,你的目的是建立一個局部變量來存儲嗎?讓咱們看看new操做符是如何下降代碼執行的性能的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; namespace Test1 { class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 1000; i++) { int a = new int(); a = 100; } sw.Stop(); Console.WriteLine("Using New operator:- " + sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < 1000; i++) { int a; a = 100; } sw.Stop(); Console.WriteLine("Without new operator:- "+ sw.ElapsedTicks); Console.ReadLine(); } } }
輸出的截圖以下:
new操做符將執行速度下降了5倍。我能夠否定輸出屏幕,但有一件事!!你一次要建立1000個變量;在咱們的項目中,咱們不會一次建立1000個變量,最多建立2到3個。
好的。你的應用程序是web應用程序嗎?若是是,那麼請檢查任何流行的web應用程序的點擊數,我確信它超過1000天天。
一樣,這一行的結論是「不要瘋狂地使用new操做符來建立整數變量」。
根據你的目的選擇最好的集合
咱們.net開發人員很是熟悉c#中的集合以及它們用來存儲值的方法。讓咱們看看它們是如何執行搜索的。查看搜索整數的性能。這是個人代碼。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; namespace Test1 { class Program { static void Main(string[] args) { List<Int32> li = new List<Int32>(1000); Dictionary<int, int> di = new Dictionary<int, int>(1000); int[] arr = new int[1000]; int a; for (int i = 0; i < 1000; i++) { li.Add(i); di.Add(i, i); arr[i] = i; } Stopwatch sw = new Stopwatch(); sw.Start(); a = li[500]; sw.Stop(); Console.WriteLine("From list:- " + sw.ElapsedTicks); sw.Start(); a = arr[500]; sw.Stop(); Console.WriteLine("From Integer array:- " + sw.ElapsedTicks); sw.Restart(); a = di[500]; sw.Stop(); Console.WriteLine("From Dictionary:- " + sw.ElapsedTicks); Console.ReadLine(); } } }
輸出在這裏:
咱們能夠清楚地看到,在字典的狀況下,搜索的性能是最差的,而在list和整數數組的狀況下,性能很是類似。
方法是好的,但不是全部時候
若是你還記得你剛開始學習編程的那幾天,你學過一個概念,就是老是實現一個方法來在代碼中實現好的練習,是的,實現一個方法來執行某些任務是很好的。方法在編程中有成千上萬的優勢,可是讓咱們看看方法是如何下降執行性能的。我再次強調,這一點並非反對方法,而是簡單地展現方法調用是一種代價高昂的機制,並提供了在何處實現方法以及在何處不實現方法的想法。讓咱們看看下面的代碼。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Net; using System.Net.NetworkInformation; namespace Test1 { class test { public static void Print() { Console.WriteLine("I am function from Class"); } } class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); test.Print(); sw.Stop(); Console.WriteLine(sw.ElapsedTicks); sw.Restart(); Console.WriteLine("I am single statement within main"); sw.Stop(); Console.WriteLine(sw.ElapsedTicks); Console.ReadLine(); } } }
下面是屏幕輸出:
在這裏,我想在輸出窗口中打印一條消息,首先,我在一個靜態函數中實現了它,並經過類名調用它,第二次我只是在主函數中編寫它。能夠,經過Console.Writeline()很是簡單。輸出屏幕顯示單行執行比函數快9倍。所以,惟一的結論是「在盲目執行某個功能以前,試着瞭解狀況並作出最佳決策」
結論
謝謝你能容忍我這麼長時間。我在個人筆記本電腦上作了上面的測試,個人筆記本電腦有core i3處理器,4GB內存和Windows環境,在程序穩定後以釋放模式輸出。若是你使用不一樣的平臺和不一樣的輸出,在評論部分有足夠的空間寫評論。
歡迎關注個人公衆號,若是你有喜歡的外文技術文章,能夠經過公衆號留言推薦給我。