技術頻道導航
HTML/CSS
.NET技術
IIS技術
PHP技術
Js/JQuery
Photoshop
Fireworks
服務器技術
操作系統(tǒng)
網(wǎng)站運營

贊助商

分類目錄

贊助商

最新文章

搜索

[C#技巧]使用using塊比沒有using塊語句消耗更少的內(nèi)存

作者:admin    時間:2023-5-5 17:46:3    瀏覽:

在前面我們介紹了幾個C#性能優(yōu)化技巧,你可以看出如下文章:

今天我再介紹一些C#技巧,這些方法可以使C#程序消耗更少的內(nèi)存,從而達到優(yōu)化性能的目的。

using塊比沒有using塊語句消耗更少的內(nèi)存

下面的例子可以證明 using 塊比沒有 using 塊語句消耗更少的內(nèi)存。

我們知道,如果我們實現(xiàn)一個 using 塊,代碼大小可能會更大,因為 using 塊在內(nèi)部會在 IL 代碼中創(chuàng)建一個 try ... catch,但是一旦它在運行時在 IL 代碼中實現(xiàn),它就會有效地處理系統(tǒng)內(nèi)存。為了證明這一點,我編寫了一個簡單的程序,如下所示。

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;  
using System.Threading;  
using System.Globalization;  
using System.Data.SqlClient;  
namespace Test1  
{  
    class Test  
    {  
        public void Test1()  
        {  
             StreamWriter wr = new StreamWriter(@"D:\text.txt");  
        }  
        public void Test2()  
        {  
             using (StreamWriter wr = new StreamWriter(@"D:\abc.txt"))  
             {   
             }  
        }  
    }   
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Test t = new Test();  
            t.Test1();  
            t.Test2();   
        }  
    }  
}  

在輸出部分,我組合了三個輸出屏幕。

 

在分配圖中,我們看到 using 塊比沒有 using 塊消耗更少的資源,因為如果我們實現(xiàn) using 塊,程序可以有效地管理內(nèi)存。

通常高級別的方法,其速度越慢

通常,你使用的方法級別越高,它就越慢。我在這里發(fā)現(xiàn)的一個常見示例是,當處于代碼的繁忙部分(可能在被調(diào)用數(shù)百萬次的循環(huán)中)時使用 LINQLINQ非常適合快速表達可能需要大量代碼行的內(nèi)容,但大家經(jīng)常會把性能擱置一旁。

別誤會我的意思——LINQ 非常適合開發(fā)出可運行的應用程序。但是在代碼庫中以性能為中心的部分,可能會放棄太多。特別是因為將如此多的操作鏈接在一起非常容易。

我自己的具體示例涉及 .SelectMany().Distinct().Count(),鑒于它被調(diào)用了數(shù)千萬次,它累積了大量的運行時間。我采用了另一種方法,將執(zhí)行時間減少了幾個數(shù)量級。

  • 雖然高級別的方法看起來更簡潔、更快,但它也可以隱藏不必要的復雜性和冗余運行時。

不要使用空析構函數(shù)

標題說明了一切——不要在你的類中添加空的析構函數(shù)。對于每個具有析構函數(shù)的類,都會將一個條目添加到 Finalize 隊列中。然后,垃圾收集器 (GC) 在調(diào)用析構函數(shù)的時候調(diào)用處理隊列。一個空的析構函數(shù)意味著這一切都是無用的。

請記住,正如我們已經(jīng)提到的,GC 執(zhí)行在性能方面并不便宜。不要不必要地為 GC 工作。

  • 避免使用空的析構函數(shù)來保留 GC:除非必要,否則不要使用終結器,并在需要時使用 SafeHandle。

避免不必要的分配

在這里,我將重點關注一個技巧:避免不必要的分配。這意味著要避免這樣的事情:

List<Product> products = new List<Product>();

products = productRepo.All();

第一行創(chuàng)建了一個完全無用的列表實例,因為緊接著的下一行返回另一個實例并將其引用分配給變量。現(xiàn)在想象上面的兩行代碼在一個執(zhí)行數(shù)千次的循環(huán)中?

不要關注示例本身,而是關注一般建議:

  • 除非確實需要,否則不要創(chuàng)建對象。

C#/.NET 具有垃圾收集功能,該過程確定哪些對象當前已過時并將其刪除以釋放內(nèi)存空間。這意味著在 C# 中,與 C++ 等語言不同,你不必手動處理刪除不再有用的對象以聲明其內(nèi)存空間的問題。相反,垃圾收集器 (GC) 會處理所有這些,因此你不必這樣做。

問題是天下沒有免費的午餐,收集過程本身會導致性能損失,所以你真的不希望 GC 一直收集,那么你就應該盡量避免這種情況。

避免不必要的裝箱和拆箱

裝箱和拆箱——就像垃圾收集——在性能方面是昂貴的過程。因此,我們希望避免不必要地包含它們。

裝箱就像創(chuàng)建一個引用類型的框并在其中放入一個值類型的值。換句話說,它包括將值類型轉換為“對象”或此值類型實現(xiàn)的接口類型。拆箱正好相反——它打開盒子并從里面提取值類型。

然而,裝箱和拆箱本身就是昂貴的過程。除此之外,當裝箱一個值時,就會在堆上創(chuàng)建另一個對象,這會給 GC 帶來額外的壓力。

那么,如何避免裝箱和拆箱呢?

通常,可以通過避免 .NET(1.0 版)中早于泛型的舊 API 來實現(xiàn)這一點,因此必須依賴于使用對象類型。例如,更喜歡 System.Collections.Generic.List 之類的通用集合,而不是 System.Collections.ArrayList 之類的集合。

  • 裝箱對于將小值類型視為引用類型非常有效,并且可以簡化你的編碼過程,但會以性能為代價。
  • 避免使用依賴于對象類型的舊 API。

總結

本文介紹了一些C#技巧,這些方法可以使C#程序消耗更少的內(nèi)存,從而達到優(yōu)化性能的目的。

相關文章

x
  • 站長推薦
/* 左側顯示文章內(nèi)容目錄 */