首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# unsafe 指標優化字串比較:以 long 區塊一次比較 4 字元

     編輯:關於C#

動機

逐字元比較字串在大量資料處理 (如基因序列、日誌分析、搜尋引擎) 時成為瓶頸。C++ 時代常將 4 個 char (8 bytes) 強轉為 long 一次比較。C# 透過 unsafe + fixed 同樣可行。

啟用 unsafe 編譯

  1. 專案屬性 → Build → 勾選 Allow unsafe code
  2. 或 .csproj 加入 <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

記憶體配置關鍵

  • char 在 .NET 為 UTF-16,佔 2 bytes。
  • long 佔 8 bytes → 可容納 4 個 char。
  • fixed (char* p = str) 釘住字串記憶體,防止 GC 移動導致指標失效。

核心比較演算法

public static unsafe bool EqualsFast(string a, string b)
{
    if (a.Length != b.Length) return false;

    // 補齊至 4 的倍數,避免越界讀取
    int pad = (4 - (a.Length % 4)) % 4;
    if (pad > 0)
    {
        a = a.PadRight(a.Length + pad, '\0');
        b = b.PadRight(b.Length + pad, '\0');
    }

    fixed (char* pa = a)
    fixed (char* pb = b)
    {
        long* la = (long*)pa;
        long* lb = (long*)pb;
        int count = a.Length / 4;

        for (int i = 0; i < count; i++)
        {
            if (la[i] != lb[i]) return false; // 一次比較 4 char
        }
    }
    return true;
}

效能基準測試 (參考)

方法平均耗時 (100 萬次比較, 20 字元字串)
string.Equals (內建)~ 45 ms
EqualsFast (unsafe long)~ 18 ms
Span<char>.SequenceEqual (.NET Core 2.1+)~ 22 ms

※ 實際差異視 CPU、JIT、字串長度、記憶體對齊而異;短字串 (<16 字元) 內建已高度優化,unsafe 優勢不明顯。

進階優化:SIMD (Vector<T> / AVX2)

using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;

public static bool EqualsSimd(ReadOnlySpan a, ReadOnlySpan b)
{
    if (a.Length != b.Length) return false;
    if (Avx2.IsSupported && Vector256.IsHardwareAccelerated)
    {
        // 256-bit = 32 bytes = 16 chars
        // 此處略過完整實作,僅示意
    }
    // fallback 到 unsafe long 或 SequenceEqual
    return EqualsFast(a.ToString(), b.ToString());
}

安全性與適用場景總結

考量說明
記憶體安全fixed 區塊結束自動解除釘住;不可在非同步/迭代器中使用指標。
信任層級需 Full Trust;沙箱環境 (如舊版 Silverlight、部分雲端函數) 禁止 unsafe。
維護成本程式碼複雜度高,建議封裝於內部工具庫,附詳細註解與單元測試。
適用場景高頻、長字串、效能關鍵路徑 (基因比對、封包檢查、全文搜尋索引建立)。

總結

C# unsafe + fixed 結合 long* 區塊比較,可將字串比較速度提升 2-3 倍。現代 .NET 建議優先使用 Span<char>.SequenceEqual 或 Vector<T> SIMD 內建 API,兼顧安全與效能;僅在極致效能需求下才引入 unsafe 手工優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved