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

Delphi汇编实现ASCII字符串比较:需忽略首字符(Chr(127))优化排序性能

定制Delphi汇编字符串比较函数(忽略首字符为Chr(127)的情况)

针对你提到的排序性能问题——因复制子串调用原CompareText导致3万条数据排序效率低下,下面直接修改汇编代码,在比较逻辑里直接处理首字符为Chr(127)的情况,无需复制子串:

function CompareCustomText(const S1, S2: string): Integer; assembler;
asm
        PUSH    ESI
        PUSH    EDI
        PUSH    EBX

        // 处理S1:若首字符是127则跳过
        MOV     ESI, EAX
        OR      ESI, ESI
        JE      @@S1Empty
        CMP     BYTE PTR [ESI], 127
        JNE     @@S1Skip
        INC     ESI             // 指针后移,跳过首字符
        DEC     DWORD PTR [ESI-4] // 临时减少字符串长度(Delphi字符串前缀是长度值)
@@S1Skip:
        MOV     EAX, [ESI-4]    // 获取S1处理后的有效长度
@@S1Empty:

        // 处理S2:逻辑同S1
        MOV     EDI, EDX
        OR      EDI, EDI
        JE      @@S2Empty
        CMP     BYTE PTR [EDI], 127
        JNE     @@S2Skip
        INC     EDI             // 跳过首字符127
        DEC     DWORD PTR [EDI-4] // 临时减少长度
@@S2Skip:
        MOV     EDX, [EDI-4]    // 获取S2处理后的有效长度
@@S2Empty:

        // 原CompareText的核心大小写不敏感比较逻辑,完全复用
        MOV     ECX, EAX
        CMP     ECX, EDX
        JBE     @@2
        MOV     ECX, EDX
@@2:    CMP     ECX, ECX
@@3:    REPE    CMPSB
        JE      @@6
        MOV     BL, BYTE PTR [ESI-1]
        CMP     BL, 'a'
        JB      @@4
        CMP     BL, 'z'
        JA      @@4
        SUB     BL, 20H
@@4:    MOV     BH, BYTE PTR [EDI-1]
        CMP     BH, 'a'
        JB      @@5
        CMP     BH, 'z'
        JA      @@5
        SUB     BH, 20H
@@5:    CMP     BL, BH
        JE      @@3
        MOVZX   EAX, BL
        MOVZX   EDX, BH
@@6:    SUB     EAX, EDX

        // 还原原字符串的长度(因为参数是const,不能修改原字符串)
        MOV     ESI, [ESP+12]   // 取出原S1的地址
        OR      ESI, ESI
        JE      @@RestoreS2
        CMP     BYTE PTR [ESI], 127
        JNE     @@RestoreS2
        INC     DWORD PTR [ESI-4] // 把临时减少的长度加回去
@@RestoreS2:
        MOV     EDI, [ESP+16]   // 取出原S2的地址
        OR      EDI, EDI
        JE      @@Exit
        CMP     BYTE PTR [EDI], 127
        JNE     @@Exit
        INC     DWORD PTR [EDI-4] // 还原S2的长度

@@Exit:
        POP     EBX
        POP     EDI
        POP     ESI
end;

关键修改说明

  1. 首字符跳过逻辑:分别对S1和S2检查首字节是否为127,若是则直接移动指针跳过该字符,同时临时调整字符串长度(Delphi短字符串的前缀4字节是长度值)
  2. 原字符串保护:因为参数是const string,不能修改原字符串的长度,所以在比较完成后必须把临时修改的长度还原,避免破坏原字符串结构
  3. 复用核心逻辑:保留原CompareText的大小写不敏感ASCII比较逻辑,保证比较行为和原函数一致

性能优势

全程不需要复制子串,直接在原字符串指针上调整后进行比较,彻底消除子串复制带来的内存分配、拷贝开销,3万条数据排序时的性能会明显提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:49:50