最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#減少代碼運(yùn)行時間的7個實(shí)戰(zhàn)技巧

 更新時間:2026年04月13日 08:35:00   作者:碼農(nóng)剛子  
C#?再次登頂!2025?年?TIOBE?年度編程語言榜單揭曉,C#?摘得桂冠,這已經(jīng)是?C#?三年內(nèi)第二次獲此殊榮,天我們就來聊聊?7?個實(shí)戰(zhàn)技巧,讓你的?C#?代碼運(yùn)行時間大幅縮短

引言

C# 再次登頂!2025 年 TIOBE 年度編程語言榜單揭曉,C# 摘得桂冠。這已經(jīng)是 C# 三年內(nèi)第二次獲此殊榮。

但語言再好,代碼寫得慢也是白搭。

你是否遇到過這樣的場景:

  • 循環(huán)處理 10 萬條數(shù)據(jù),跑了幾分鐘
  • 字符串拼接內(nèi)存爆炸
  • LINQ 查詢看似優(yōu)雅,實(shí)則性能堪憂

今天我們就來聊聊 7 個實(shí)戰(zhàn)技巧,讓你的 C# 代碼運(yùn)行時間大幅縮短。

一、選對數(shù)據(jù)結(jié)構(gòu):O(n) vs O(1)

錯誤示范

// 用 List 查找,時間復(fù)雜度 O(n)
var list = new List<int> { 1, 2, 3, /* ...10萬條 */ };
if (list.Contains(99999)) { /* ... */ }

正確做法

// 用 HashSet 查找,時間復(fù)雜度 O(1)
var set = new HashSet<int> { 1, 2, 3, /* ...10萬條 */ };
if (set.Contains(99999)) { /* ... */ }

性能對比

操作ListHashSetDictionary
查找O(n)O(1)O(1)
插入O(1)O(1)O(1)
刪除O(n)O(1)O(1)

經(jīng)驗(yàn)法則

  • 頻繁查找 → HashSet / Dictionary
  • 需要索引訪問 → List
  • 需要排序 → SortedSet / SortedDictionary

二、字符串拼接:告別 String,擁抱 StringBuilder

為什么 String 慢

String 是不可變對象。每次拼接都會創(chuàng)建新對象:

string s = "a";
s += "b";  // 創(chuàng)建新對象 "ab",舊對象 "a" 等待 GC
s += "c";  // 創(chuàng)建新對象 "abc",舊對象 "ab" 等待 GC

循環(huán)拼接 10000 次?恭喜,你創(chuàng)建了 10000 個字符串對象。

StringBuilder 登場

var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
    sb.Append(i);
}
string result = sb.ToString();

性能對比

// 測試:拼接 10000 次字符串

// String: 約 150ms
string s = "";
for (int i = 0; i < 10000; i++) s += i;

// StringBuilder: 約 1ms
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++) sb.Append(i);

150 倍性能差距,這就是選對工具的力量。

三、Span:零拷貝內(nèi)存操作

什么是 Span

Span 是 C# 7.2 引入的高性能內(nèi)存結(jié)構(gòu),它:

  • 指向連續(xù)內(nèi)存區(qū)域
  • 無需復(fù)制數(shù)據(jù)
  • 棧分配,無 GC 壓力

傳統(tǒng)方式 vs Span

// 傳統(tǒng)方式:截取子字符串會分配新內(nèi)存
string text = "Hello, ManongGangzi!";
string sub = text.Substring(0, 5);  // 新分配 "Hello"

// Span 方式:零分配
ReadOnlySpan<char> span = text.AsSpan();
ReadOnlySpan<char> subSpan = span.Slice(0, 5);  // 無分配

實(shí)戰(zhàn)案例:解析數(shù)字

// 傳統(tǒng)方式
string numStr = "12345";
int num = int.Parse(numStr);  // 已分配的字符串

// Span 方式
ReadOnlySpan<char> span = "12345".AsSpan();
int num = int.Parse(span);  // 直接解析,無需中間字符串

適用場景

  • 高頻字符串處理
  • 大數(shù)組切片操作
  • 網(wǎng)絡(luò)數(shù)據(jù)包解析
  • 游戲開發(fā)中的緩沖區(qū)操作

四、異步編程:不要阻塞線程

錯誤示范:同步阻塞

// 阻塞主線程
var result = httpClient.GetStringAsync(url).Result;

這會導(dǎo)致:

  • 線程池饑餓
  • 應(yīng)用響應(yīng)變慢
  • 死鎖風(fēng)險

正確做法:async/await

// 非阻塞,釋放線程
public async Task<string> GetDataAsync(string url)
{
    return await httpClient.GetStringAsync(url);
}

并行處理多個任務(wù)

// 串行:總時間 = sum(每個任務(wù)時間)
var data1 = await GetDataAsync(url1);
var data2 = await GetDataAsync(url2);
var data3 = await GetDataAsync(url3);

// 并行:總時間 = max(每個任務(wù)時間)
var tasks = new[]
{
    GetDataAsync(url1),
    GetDataAsync(url2),
    GetDataAsync(url3)
};
var results = await Task.WhenAll(tasks);

3 個請求各 1 秒

  • 串行:3 秒
  • 并行:1 秒

五、LINQ 陷阱:延遲執(zhí)行 vs 立即執(zhí)行

延遲執(zhí)行的坑

var numbers = new List<int> { 1, 2, 3 };

var query = numbers.Where(n => n > 1);  // 此時未執(zhí)行

numbers.Add(4);  // 修改源數(shù)據(jù)

var result = query.ToList();  // 這里才執(zhí)行!
// result = [2, 3, 4],包含了后添加的 4

多次枚舉的性能問題

var query = numbers.Where(n => n > 1);

// 錯誤:每次都重新執(zhí)行
if (query.Any())         // 執(zhí)行一次
{
    var first = query.First();  // 又執(zhí)行一次
    var count = query.Count();  // 再執(zhí)行一次
}

// 正確:緩存結(jié)果
var list = numbers.Where(n => n > 1).ToList();
if (list.Any())
{
    var first = list.First();  // 從緩存讀取
    var count = list.Count();  // 從緩存讀取
}

性能對比

操作延遲執(zhí)行立即執(zhí)行 (ToList)
多次訪問每次重新計(jì)算一次計(jì)算,多次讀取
內(nèi)存占用需要存儲結(jié)果
適用場景單次遍歷多次訪問

六、避免裝箱拆箱

什么是裝箱拆箱

int value = 42;
object obj = value;      // 裝箱:值類型 → 引用類型
int back = (int)obj;     // 拆箱:引用類型 → 值類型

每次裝箱都會:

  • 在堆上分配內(nèi)存
  • 觸發(fā) GC

錯誤示范

var list = new ArrayList();  // 非泛型集合
list.Add(1);    // 裝箱
list.Add(2);    // 裝箱
int sum = 0;
foreach (int i in list)  // 拆箱
{
    sum += i;
}

正確做法

var list = new List<int>();  // 泛型集合
list.Add(1);    // 無裝箱
list.Add(2);    // 無裝箱
int sum = 0;
foreach (int i in list)  // 無拆箱
{
    sum += i;
}

性能差異

循環(huán) 100 萬次:

  • ArrayList:約 50ms
  • List:約 5ms

10 倍差距,這就是泛型的威力。

七、對象池:復(fù)用而非重建

為什么需要對象池

頻繁創(chuàng)建銷毀對象會:

  • 增加 GC 壓力
  • 觸發(fā)頻繁 GC 暫停
  • 影響應(yīng)用響應(yīng)時間

使用 ArrayPool

using System.Buffers;

// 傳統(tǒng)方式:每次分配新數(shù)組
byte[] buffer = new byte[1024];
ProcessData(buffer);

// 對象池方式:復(fù)用數(shù)組
var pool = ArrayPool<byte>.Shared;
byte[] buffer = pool.Rent(1024);
try
{
    ProcessData(buffer);
}
finally
{
    pool.Return(buffer);  // 歸還池中
}

使用 MemoryPool

using System.Buffers;

var pool = MemoryPool<byte>.Shared;
using var memoryOwner = pool.Rent(1024);
ProcessData(memoryOwner.Memory);
// 自動歸還

適用場景

  • 高頻臨時數(shù)組
  • 網(wǎng)絡(luò)緩沖區(qū)
  • 游戲中的臨時對象
  • 圖像處理中的像素緩沖

總結(jié):7 個優(yōu)化清單

技巧收益適用場景
選對數(shù)據(jù)結(jié)構(gòu)O(n) → O(1)頻繁查找
StringBuilder150x 提升字符串拼接
Span零拷貝內(nèi)存操作
async/await并行加速I/O 操作
LINQ ToList避免重復(fù)計(jì)算多次訪問
泛型集合10x 提升避免裝箱
對象池減少 GC高頻創(chuàng)建

寫在最后

性能優(yōu)化不是一蹴而就的,而是點(diǎn)滴積累

記住三個原則:

  1. 先測量,再優(yōu)化 —— 用 BenchmarkDotNet 找到真正的瓶頸
  2. 選對工具 —— 數(shù)據(jù)結(jié)構(gòu)、API、設(shè)計(jì)模式
  3. 避免過早優(yōu)化 —— 可讀性優(yōu)先,性能瓶頸出現(xiàn)時再優(yōu)化

到此這篇關(guān)于C#減少代碼運(yùn)行時間的7個實(shí)戰(zhàn)技巧的文章就介紹到這了,更多相關(guān)C#減少代碼運(yùn)行時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 圖文介紹c#封裝方法

    圖文介紹c#封裝方法

    在本篇內(nèi)容里小編給大家分享的是關(guān)于c#使用封裝方法以及相關(guān)知識點(diǎn),對此有需要的朋友們可以學(xué)習(xí)下。
    2018-12-12
  • C#實(shí)現(xiàn)翻轉(zhuǎn)字符串的方法

    C#實(shí)現(xiàn)翻轉(zhuǎn)字符串的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)翻轉(zhuǎn)字符串的方法,涉及C#操作字符串的技巧,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-04-04
  • 如何保存Unity中的Log日志

    如何保存Unity中的Log日志

    這篇文章主要介紹了如何保存Unity中的Log日志的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C#實(shí)現(xiàn)將Excel工作表拆分為獨(dú)立文件

    C#實(shí)現(xiàn)將Excel工作表拆分為獨(dú)立文件

    在日常數(shù)據(jù)處理中,你是否經(jīng)常遇到需要將一個包含多個工作表的Excel文件,根據(jù)每個工作表的內(nèi)容,分別保存成獨(dú)立的Excel文件,下面小編就來和大家講講如何使用C#實(shí)現(xiàn)這一功能吧
    2025-12-12
  • 詳解C# ConcurrentBag的實(shí)現(xiàn)原理

    詳解C# ConcurrentBag的實(shí)現(xiàn)原理

    ConcurrentBag<T>實(shí)現(xiàn)了IProducerConsumerCollection<T>接口,該接口主要用于生產(chǎn)者消費(fèi)者模式下,可見該類基本就是為生產(chǎn)消費(fèi)者模式定制的。然后還實(shí)現(xiàn)了常規(guī)的IReadOnlyCollection<T>類,實(shí)現(xiàn)了該類就需要實(shí)現(xiàn)IEnumerable<T>、IEnumerable、 ICollection類
    2021-06-06
  • C#實(shí)現(xiàn)串口通信的四種靈活策略和避坑指南

    C#實(shí)現(xiàn)串口通信的四種靈活策略和避坑指南

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)串口通信的四種靈活策略和避坑的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-01-01
  • C#操作config文件的具體方法

    C#操作config文件的具體方法

    這篇文章介紹了在C#中對config文件的操作,有需要的朋友可以參考一下
    2013-07-07
  • 兩路歸并的數(shù)組與鏈表的實(shí)現(xiàn)方法

    兩路歸并的數(shù)組與鏈表的實(shí)現(xiàn)方法

    本篇文章對兩路歸并的數(shù)組與鏈表的實(shí)現(xiàn)方法進(jìn)行了分析介紹。需要的朋友參考下
    2013-05-05
  • C#先判斷是否存在再創(chuàng)建文件夾或文件與遞歸計(jì)算文件夾大小

    C#先判斷是否存在再創(chuàng)建文件夾或文件與遞歸計(jì)算文件夾大小

    這篇文章介紹了C#先判斷是否存在再創(chuàng)建文件夾或文件與遞歸計(jì)算文件夾大小的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • c#?COM組件原理詳解

    c#?COM組件原理詳解

    本文主要介紹了c#?COM組件原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08

最新評論

涪陵区| 大邑县| 锦州市| 永靖县| 宜黄县| 江城| 汾西县| 大石桥市| 花垣县| 安龙县| 巴南区| 冀州市| 乌拉特后旗| 临江市| 曲松县| 沂源县| 黑山县| 枣阳市| 南昌市| 江川县| 南靖县| 钟山县| 隆化县| 新安县| 腾冲县| 潮安县| 墨脱县| 隆尧县| 上虞市| 泸溪县| 新郑市| 舞钢市| 鹤岗市| 莱西市| 盐亭县| 米易县| 如皋市| 鲁山县| 天峻县| 宝应县| 诸城市|