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

贊助商

分類目錄

贊助商

最新文章

搜索

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

作者:admin    時(shí)間:2023-5-5 17:46:3    瀏覽:

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

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

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

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

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

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();   
        }  
    }  
}  

在輸出部分,我組合了三個(gè)輸出屏幕。

 

在分配圖中,我們看到 using 塊比沒有 using 塊消耗更少的資源,因?yàn)槿绻覀儗?shí)現(xiàn) using 塊,程序可以有效地管理內(nèi)存。

通常高級(jí)別的方法,其速度越慢

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

別誤會(huì)我的意思——LINQ 非常適合開發(fā)出可運(yùn)行的應(yīng)用程序。但是在代碼庫(kù)中以性能為中心的部分,可能會(huì)放棄太多。特別是因?yàn)閷⑷绱硕嗟牟僮麈溄釉谝黄鸱浅H菀住?/p>

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

  • 雖然高級(jí)別的方法看起來(lái)更簡(jiǎn)潔、更快,但它也可以隱藏不必要的復(fù)雜性和冗余運(yùn)行時(shí)。

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

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

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

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

避免不必要的分配

在這里,我將重點(diǎn)關(guān)注一個(gè)技巧:避免不必要的分配。這意味著要避免這樣的事情:

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

products = productRepo.All();

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

不要關(guān)注示例本身,而是關(guān)注一般建議:

  • 除非確實(shí)需要,否則不要?jiǎng)?chuàng)建對(duì)象。

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

問題是天下沒有免費(fèi)的午餐,收集過程本身會(huì)導(dǎo)致性能損失,所以你真的不希望 GC 一直收集,那么你就應(yīng)該盡量避免這種情況。

避免不必要的裝箱和拆箱

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

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

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

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

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

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

總結(jié)

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

相關(guān)文章

標(biāo)簽: asp.net  CSharp  代碼性能  優(yōu)化  using塊  
x
  • 站長(zhǎng)推薦
/* 左側(cè)顯示文章內(nèi)容目錄 */