首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 字串搜尋優化實戰:從 Pos 到指標掃描,效能提升 35%

     編輯:Delphi

離線瀏覽器開發中需大量解析 HTML,字串搜尋是 CPU 熱點。標準 Pos 僅支援首次匹配、區分大小寫,無法滿足「不分大小寫」「找最後一次出現」等需求。本文展示從朴素實作到指標掃描的優化全過程,實測在 Duron 700/256MB 環境下,優化版比原版快 35%,且程式碼更簡潔。

高精度計時基礎

  • GetTickCount:毫秒級,精度不足。
  • QueryPerformanceCounter / QueryPerformanceFrequency:利用 8254 定時器晶片,理論精度 1/1,193,180 秒,配合大循環次數可達微秒級測量。

var C1, C2, Freq: Int64;
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(C1);
// 執行待測代碼 10000 次
QueryPerformanceCounter(C2);
ShowMessage('Ticks: ' + IntToStr(C2 - C1) + ' Freq: ' + IntToStr(Freq));

需求:RightPosEx — 找子串最後一次出現位置,不分大小寫

版本 1:朴素刪除法(極慢)


function RightPos(const SubStr, S: String): Integer;
var iPos: Integer; Tmp: String;
begin
  Tmp := S; Result := 0;
  iPos := Pos(SubStr, Tmp);
  while iPos <> 0 do begin
    Delete(Tmp, 1, iPos + Length(SubStr) - 1); // 每次重新分配記憶體、移動資料
    Result := Result + iPos;
    iPos := Pos(SubStr, Tmp);
    if iPos = 0 then Break;
    Result := Result + Length(SubStr) - 1;
  end;
end;

致命傷:Delete 內部呼叫 Move + _LStrSetLength,涉及記憶體重新分配與大量資料搬移,CPU 開銷極大。

版本 2:指標掃描法(快 35%)


function RightPosEx(const SubStr, S: String): Integer;
var
  I, J, L: Integer;
  PStr, PSub: PChar;
begin
  PStr := PChar(S);      // 轉 PChar 獲取指標
  PSub := PChar(SubStr);
  Result := 0;
  L := Length(SubStr);
  for I := 0 to Length(S) - 1 do begin
    for J := 0 to L - 1 do
      if PStr[I + J] <> PSub[J] then Break;
    if J = L then Result := I + 1; // 記錄最後匹配位置 (1-based)
  end;
end;
  • 單次線性掃描,無記憶體分配、無資料搬移。
  • 直接操作字元陣列,CPU 緩存友好。
  • 若需不分大小寫,比較前統一 UpCase 或用 CharLowerBuff。

實測數據對比 (10,000 次循環)

函數QueryPerformanceCounter Ticks相對耗時
Pos (系統)150,000基準 1.00
RightPos (刪除法)217,0001.45×
RightPosEx (指標法)160,0001.07×

指標法僅比系統優化過的 Pos 慢 7%,但功能更強(找最後、可擴充不分大小寫);刪除法則慢 45%。

進階優化方向

  • Boyer-Moore / KMP 演算法:長模式串、多次搜尋同一主串時極佳。
  • SSE/AVX 向量化:現代 CPU 可 16/32 字元並行比較。
  • 保持 Delphi String 而非轉 PChar:避免轉換開銷,但需注意 Copy-on-Write 語意。
  • 預處理索引:如建立 Suffix Array、Trie 樹,適合超大文本多次查詢。

工程取捨原則

「效能優化到哪裡為止,取決於熱點比例與維護成本。」
若該函數佔總 CPU < 5%,進一步優化投資報酬率極低;若為核心解析引擎佔 50%+,則值得引入複雜演算法。

本案例展示:避開高階封裝的記憶體操作(Delete、Pos 內部 Move),改用底層指標線性掃描,即可在不犧牲可讀性前提下大幅提升效能,是 Delphi 字串處理優化的通用範式。

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