C# 效能最佳化之斤斤計較篇 一

來源:互聯網
上載者:User

今天,我想跟大家聊一聊C#的效能最佳化,當然,這裡並不談基本的原則,這些都假設你已經非常精通了,本文聊的是要爭取幾個毫秒的程式。關於基本的效能最佳化,可以參考園子裡的文章。比如:

.NET 效能最佳化方法總結

先說說我的測試環境:

一台典型的膝上型電腦,Windows 7中文版,.net Framework用的是4.5版本,VS是現在VS11 beta版。我也是用VS2008這樣的環境測試了下面的所有情境,發現沒有任何區別,所以就以VS11為基準了。

所有測試資料都是編譯為Relase,且不包含PDB,直接雙擊運行而非在VS環境下執行。點擊這裡下載原始碼。

言歸正傳,先測試第一點:

 

靜態方法比執行個體方法快嗎?

我們總是從各個渠道聽說:靜態方法比執行個體方法要快,所以,我想親自試試。測試方法很簡單,迴圈調用執行個體方法和靜態方法。

    /// <summary>    /// 這是一個普通類,調用執行個體的方法    /// </summary>    public class C1 {        public void DoLoop() {            for (int i = 0; i < int.MaxValue; i++) {                DoIt();            }         }        private void DoIt() {        }    }    /// <summary>    /// 使用靜態方法調用。    /// </summary>    public static class C2 {        public static void DoLoop() {            for (int i = 0; i < int.MaxValue; i++) {                DoIt();            }        }        private static void DoIt() {        }    }

測試結果如下:

測試多次,基本偏差不大,只能說,靜態方法比執行個體方法快那麼可憐的一點點,鑒於執行個體方法的靈活性遠大於靜態方法,所以還是一般使用執行個體方法吧。

也實驗過,在方法中訪問執行個體欄位和靜態欄位,發現也沒有區別,所以不再單獨羅列代碼。

 

避免方法內建立執行個體的情況

這個要討論的問題有點難說明,我們還是先看一看.net內部的代碼吧,下面是一段Collection<T>.Add的方法:

public void Add(T item){if (this.items.IsReadOnly){ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);}int count = this.items.Count;this.InsertItem(count, item);}

注意ThrowHelper類,如果換成我們自己寫,一句話就搞定了:throw new NotSupportedException。為什麼微軟要這麼寫呢?

老外有解釋:Why does SortedList implementation use ThrowHelper instead of throwing directly?

其實,我也是信奉此真理,而且就在前一段時間,一位同事還找我問,兩段幾乎一樣的代碼,為什麼測試效能有差距,結果我按照此原理,將異常拋出放在外面,結果真的變好了。

現在,我還要再次測試一下,我相信的是資料:

    class C1 {        private Dictionary<int, int> _dict = new Dictionary<int, int>() ;        public C1() {            _dict.Add(1, 1);            _dict.Add(2, 2);        }        public void Do1() {            object obj = new object();            for (int i = 0; i < int.MaxValue/100; i++) {                GetItOne(1);            }        }        //這個方法,在內部可能建立執行個體        private int GetItOne(int key) {            int value;            if (!_dict.TryGetValue(key,out value)) {                throw new ArgumentOutOfRangeException("key");            }            return value;        }        public void Do2() {            for (int i = 0; i < int.MaxValue/100; i++) {                GetItTwo(1);            }        }        //這個方法,將建立執行個體的代碼移動到外部        private int GetItTwo(int key) {            int value;            if (!_dict.TryGetValue(key, out value)) {                ThrowArgumentOutOfRangeException();            }            return value;        }        private static void ThrowArgumentOutOfRangeException() {            throw new ArgumentOutOfRangeException("key");        }    }

測試結果是:

基本上,會快0.06秒左右,但是如此大的迴圈得到的好處並不是那麼的明顯,但有作用。這種寫法還是比較舒服的,所以還是建議大家用吧。

 

下篇我將實驗:數組的枚舉,類和結構建立的成本。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.