You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用Sorted属性时高效删除TStrings重复项的性能最优方案

最优实现方案:哈希表辅助的线性遍历

针对你的需求(不依赖TStrings.Sorted、去重并保留原顺序、处理1.2MB IRC日志),基于哈希表的线性遍历是性能最优的实现方式,时间复杂度为O(n),远优于暴力对比的O(n²),完全适配你的数据规模。

核心逻辑

通过哈希表快速记录已出现过的日志行,遍历原列表时仅将未出现过的行加入结果列表,既能保证去重,又能严格保留原有顺序。哈希表的平均查找时间为O(1),整体遍历过程仅需一次线性扫描。

具体实现(Delphi环境)

方案1:使用TDictionary<string, Boolean>(兼容全Delphi版本)

function RemoveDuplicatesKeepOrder(const Source: TStrings): TArray<string>;
var
  Seen: TDictionary<string, Boolean>;
  I: Integer;
  CurrentLine: string;
  ResultIndex: Integer;
begin
  // 预分配结果数组容量,避免多次内存重分配
  SetLength(Result, Source.Count);
  ResultIndex := 0;
  
  // 初始化哈希表,设置初始容量为原列表行数,减少扩容开销
  Seen := TDictionary<string, Boolean>.Create(Source.Count);
  try
    for I := 0 to Source.Count - 1 do
    begin
      CurrentLine := Source.Strings[I];
      if not Seen.ContainsKey(CurrentLine) then
      begin
        Seen.Add(CurrentLine, True);
        Result[ResultIndex] := CurrentLine;
        Inc(ResultIndex);
      end;
    end;
    // 截断结果数组至实际有效长度
    SetLength(Result, ResultIndex);
  finally
    Seen.Free;
  end;
end;

方案2:使用THashSet<string>(Delphi XE7+,更轻量)

THashSet是专门的集合类型,无需存储冗余值,内存开销略低于TDictionary:

function RemoveDuplicatesKeepOrder(const Source: TStrings): TArray<string>;
var
  Seen: THashSet<string>;
  I: Integer;
  CurrentLine: string;
  ResultIndex: Integer;
begin
  SetLength(Result, Source.Count);
  ResultIndex := 0;
  
  Seen := THashSet<string>.Create(Source.Count);
  try
    for I := 0 to Source.Count - 1 do
    begin
      CurrentLine := Source.Strings[I];
      // Add方法返回True表示该行未在集合中存在
      if Seen.Add(CurrentLine) then
      begin
        Result[ResultIndex] := CurrentLine;
        Inc(ResultIndex);
      end;
    end;
    SetLength(Result, ResultIndex);
  finally
    Seen.Free;
  end;
end;

性能优化细节

  1. 预分配内存:结果数组初始容量设为原列表行数,避免动态扩容的内存拷贝开销;哈希表初始容量匹配原列表规模,减少哈希冲突和扩容次数。
  2. 避免冗余操作:直接引用原列表的字符串(Delphi字符串为引用计数类型,无需额外拷贝),减少内存消耗。
  3. 选择合适的哈希结构:THashSet比TDictionary更适合纯集合场景,内存占用更低。

方案对比

  • 暴力遍历法:每次新行都和已处理行逐一对比,时间复杂度O(n²),对于1.2MB日志(约1万-2万行)会产生百万级别的对比操作,性能极差,完全不推荐。
  • 依赖TStrings.Sorted:会打乱原有顺序,且不符合你的禁用要求,排除。

适配1.2MB日志的性能表现

该方案处理1万-2万行的IRC日志仅需毫秒级时间,内存开销仅为存储唯一行的引用+哈希表结构,完全在常规程序的内存承受范围内。

内容的提问来源于stack exchange,提问作者WayOfTheWright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:42:41