<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 原則16:避免創建不需要的對象 **By D.S.Qiu** **尊重他人的勞動,支持原創,轉載請注明出處:[http://dsqiu.iteye.com](http://dsqiu.iteye.com)** 垃圾回收期在管理內存方面非常出色,它非常高效地移除不再使用的對象。但是無論你如何看待它,分配和銷毀一個基于堆內存的對象花費處理器時間比分配和銷毀不是基于堆內存的對象要多。在函數內創建大量的引用類型對象會引入嚴重的性能消耗問題。 所以不能讓垃圾回收器超負荷工作。你可以借鑒一些簡單的技巧最小化垃圾回收器的工作。所有的引用類型對象,即使是局部變量,都被分配存儲在堆內存上。每個引用類型的局部變量在函數結束都會變為垃圾。一個最常見的壞實踐是在 Windows 畫圖處理申請 GDI 對象: ``` // Sample one protected override void OnPaint(PaintEventArgs e) { // Bad. Created the same font every paint event. using (Font MyFont = new Font("Arial", 10.0f)) { e.Graphics.DrawString(DateTime.Now.ToString(), MyFont, Brushes.Black, new PointF(0, 0)); } base.OnPaint(e); } ``` OnPainr() 會被頻繁調用。每次被調用,你都會創建另一個包含相同設置的 Font 對象。垃圾回收器每次都需要為你清理。這間接導致低效。 相反,將 Font 對象從局部變量提升為成員變量。每次都重復使用相同的字體話窗口: ``` private readonly Font myFont = new Font("Arial", 10.0f); protected override void OnPaint(PaintEventArgs e) { e.Graphics.DrawString(DateTime.Now.ToString(), myFont, Brushes.Black, new PointF(0, 0));base.OnPaint(e); } ``` 你的程序不會每個繪畫事件都產生垃圾。垃圾回收器的負擔更少。你的程序也會跑的更快一點。當你把一個實現 IDisposable 的對象由局部變量提升為成員變量,如字體,那么你這個的類也要實現 IDisposable 。原則18會解釋為什么那樣做是對的。 如果一個引用類型的局部變量在函數中使用非常頻繁,你需要將它提升為成員變量(值類型無關緊要)。上面繪畫的字體就是最好的例子。只有常用的局部變量要頻繁被訪問才是好的候選。不是頻繁調用就不用了。你應該避免重復創建相同的對象,也不要將每個局部變量轉換為成員變量。 前面例子的靜態屬性 Brushes.Black 又是一個演示避免重復創建相同對象的技術。將常用的對象實例創建為靜態成員變量。考慮前面例子中的黑色畫刷。每次在要窗口使用黑色畫東西,你都需要黑色畫刷。如果你每次需要畫東西都是申請一個新的,你會在運行中創建和銷毀大量的黑色畫刷。第一種做法是在你類中創建一個黑色畫刷的成員變量,但這是遠遠不夠的。程序可能創建大量窗口和控制,就會創建大量的黑色畫刷。 .NET 框架設計者考慮到這點并且只創建一個黑色畫刷讓你需要的時候重復使用。 Brushes 類包含了大量的靜態 Brush 對象,每個都是一種的常見顏色。在內部, Brushes 類使用懶惰算法,即只有當你需要的時候才創建。下面就是一個簡單的實現: ``` private static Brush blackBrush; public static Brush Black { get { if (blackBrush == null) blackBrush = new SolidBrush(Color.Black); return blackBrush; } } ``` 當你第一次使用黑色畫刷, Brushes 類就會創建它。 Brushes 類保持黑色畫刷的一個簡單的引用,當你再需要的時就會返回這個引用。結果就是你只創建了一個黑色畫刷并且可以一直重復使用。并且,如果你程序不需要穿件一個特殊的資源——比如,檸檬綠畫刷——它就不會被創建。框架提供方法限制了對象的創建,在你完成目標的情況下使用最少的對象集。學會在你的程序中使用這樣的技巧。 你已經學會兩種技巧減少申請對象的數量,就像完成自己的業務一樣。你可以將經常使用的局部變量提升為成員變量。你也可以使用單例模式讓一個類提供常用的實例。最后這種技巧還包含了不可變類型的最終值。 System.String 類是不可變的:你構建好一個字符串之后,這個字符串的內容就不會被修改。任何時候你寫的代碼看起來像修改了字符串的內容,其實是創建了一個新的字符串對象,而舊的字符串就變為垃圾。這看似很無辜的實現: ``` string msg = "Hello, "; msg += thisUser.Name; msg += ". Today is "; msg += System.DateTime.Now.ToString(); ``` 和下面的寫法一樣是低效的: ``` string msg = "Hello, "; // Not legal, for illustration only: string tmp1 = new String(msg + thisUser.Name); msg = tmp1; // "Hello " is garbage. string tmp2 = new String(msg + ". Today is "); msg = tmp2; // "Hello <user>" is garbage. string tmp3 = new String(msg + DateTime.Now.ToString()); msg = tmp3; // "Hello <user>. Today is " is garbage. ``` 字符串 tmp1, tmp2,和 tmp3 以及開始創建的消息(“Hello”),都是垃圾。string 類的 += 方法會創建新的字符串并返回。在字符串上連接字符不會修改原來的字符串。像前面的構造,可以使用 string.Format() 方法: ``` string msg = string.Format("Hello, {0}. Today is {1}",thisUser.Name, DateTime.Now.ToString()); ``` 對于更復雜的字符串操作,你可以使用 StringBuilder 類: ``` StringBuilder msg = new StringBuilder("Hello, "); msg.Append(thisUser.Name); msg.Append(". Today is "); msg.Append(DateTime.Now.ToString()); string finalMsg = msg.ToString(); ``` StringBuilder 是一個可變字符串類用于構建不可變的 string 對象。在形成不可變 string 對象之前,它提供了配套的可變字符串方法去創建和修改文本內容。使用 StringBuilder 創建最終版本的字符串對象。更重要的是,學會這種設計思想。考慮當你設計不可變類型時(查看原則20),考慮創建一個對象去構建需要多次構造而成的最終對象。可以讓使用者一步一步構建對象,并且維護這個不可變的類型。 垃圾回收器高效地管理你程序使用的內存。但是記住創建和銷毀堆內存對象仍會花費時間。避免創建大量對象,不要創建你不需要的對象。同時避免創建在函數內部創建多個引用類型對象。相反,考慮提升局部變量為成員變量,或者為你的類型創建大多數常用的實例。最后,考慮創建一個可變類來構建不可變類。 小結: 這則原則相對簡短,但是非常重要,尤其是對于菜鳥碼農,總之,避免重復創建對象。 歡迎各種不爽,各種噴,寫這個純屬個人愛好,秉持”分享“之德! 有關本書的其他章節翻譯請[點擊查看](/category/297763),轉載請注明出處,尊重原創! 如果您對D.S.Qiu有任何建議或意見可以在文章后面評論,或者發郵件(gd.s.qiu@gmail.com)交流,您的鼓勵和支持是我前進的動力,希望能有更多更好的分享。 轉載請在**文首**注明出處:[http://dsqiu.iteye.com/blog/2078554](/blog/2078554) 更多精彩請關注D.S.Qiu的博客和微博(ID:靜水逐風)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看