HexToInt的几个函数速度比较

博客展示了多个十六进制字符串转整数的函数,如HexToInt_tseug0、HexToInt_tseug1等,包含汇编和常规代码实现。还提供了测试函数TestHexToInt,用于测试各转换函数的性能,通过多次执行拉开时间差距,并在按钮点击事件中输出各函数的执行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

unit unit1 ;

interface

uses
 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms
,
 
Dialogs, StdCtrls
;

type
 
TForm1 = class(TForm
)
   
Button1: TButton
;
   
Memo1: TMemo
;
   
procedure Button1Click(Sender: TObject
);
 
private
   
{ Private declarations }
 
public
   
{ Public declarations }
 
end
;

var
 
Form1: TForm1
;

implementation

{$R *.dfm}

const
 
HexStr: String = 'ABCD1234'
;
 
CalcTimes: Integer = 1000000
;

type
 
THexToIntFunc = function(const S: String): DWORD
;

function HexToInt_tseug0(const S: String): DWORD
;
asm
 
PUSH EBX
  PUSH ESI

  MOV ESI, EAX
//字符串地址
 
MOV EDX, [EAX-4]
//读取字符串长度

 
XOR EAX, EAX
//初始化返回值
 
XOR ECX, ECX
//临时变量

 
TEST ESI, ESI
//判断是否为空指针
 
JZ @@2
  TEST EDX, EDX
//判断字符串是否为空
 
JLE @@2
  MOV BL, $20
@@0:
  MOV CL, [ESI]
  INC ESI

  OR CL, BL
//如果有字母则被转换为小写字母
 
sub CL, '0'
  JB @@2
// < '0' 的字符
 
CMP CL, $09
  JBE @@1
// '0'..'9' 的字符
 
sub CL, 'a'-'0'-10
  CMP CL, $0A
  JB @@2
// < 'a' 的字符
 
CMP CL, $0F
  JA @@2
// > 'f' 的字符
@@1:
// '0'..'9', 'A'..'F', 'a'..'f'
 
SHL EAX, 4
  OR EAX, ECX
  DEC EDX
  JNZ @@0
  JMP @@3
@@2:
  XOR EAX, EAX
// 非法16进制字符串
@@3:
  POP ESI
  POP EBX
  RET
end
;

function HexToInt_tseug1(const S: String): DWORD
;
var
 
I : Integer
;
begin
 
Result := 0
;
 
for I := 1 to Length(s)
do
    begin
    case
s[I]
of
     
'0'..'9': Result := Result * 16 + Ord(S[I]) - Ord('0'
);
     
'A'..'F': Result := Result * 16 + Ord(S[I]) - Ord('A') + 10
;
     
'a'..'f': Result := Result * 16 + Ord(S[I]) - Ord('a') + 10
;
   
else
     
Result := 0
;
     
Exit
;
     
end
;
   
end
end
;

function HexToInt_DoubleWood(const S: string): DWORD
;
const
 
Convert: array[0..255] of Integer
=
    (
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
,
     -
1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,
     -
1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-
1
    
);
var
 
I: Integer
;
 
v: Integer
;
begin
 
Result := 0
;
 
if Pointer(s) = nil then exit
;
 
for I := 1 to PInteger(Integer(s) - 4)^
do
  begin
    begin
     
V := Convert[ord(s[i
])];
     
if V<0
then
      begin
       
Result := 0
;
       
Exit
;
     
end
;
     
result := (result * 16) or V
;
   
end
;
 
end
;
end
;

function HexToInt_beta1(const S: string): DWORD
;
const
 
ValidateTbl: array [0..255] of Byte
= (
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16
,
   
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
);
asm
 
push ebx
  push ecx
  push edx
  push esi
  push edi

  mov esi, eax
//字符串地址
 
mov ecx, [eax-4]
//读取字符串长度
 
test esi, esi
//判断是否为空指针
 
jz @Err
  test ecx, ecx
//判断字符串是否为空
 
jle @Err

  xor eax, eax
  lea edi, ValidateTbl
  mov edx, ecx
  xor ebx, ebx
  @LoopValidate:
  mov bl, [esi]
  mov bl, [edi][ebx]
  test ebx, 16
  jnz @Err

  shl eax, 4
  or eax, ebx

  inc esi
  dec edx
  jnz @LoopValidate

  jmp @Ext
  @Err:
  xor eax, eax
// 非法16进制字符串
 
@Ext:

  pop edi
  pop esi
  pop edx
  pop ecx
  pop ebx
end
;

function HexToInt_beta2(const S: string): DWORD
;
const
 
ValidateTbl: array [0..255] of Byte
= (
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16
,
   
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
,
   
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
);
asm
 
push ebx
  push ecx
  push edx
  push esi
  push edi

  mov edi, esp
  push 0

  mov esi, eax
//字符串地址
 
mov ecx, [eax - 4]
//读取字符串长度
 
test esi, esi
//判断是否为空指针
 
jz @Err
  test ecx, ecx
//判断字符串是否为空
 
jle @Err

  lea eax, ValidateTbl
  xor edx, edx
  xor ebx, ebx

  test ecx, 1
  jz @LeftBytes

 
//FirstByte:
 
mov bl, [esi]
  mov bl, [eax][ebx]
  test ebx, 16
  jnz @Err
  shl bl, 4
  dec edi
  mov [edi], bl

  dec ecx
  jz @Ext

  @LeftBytes:
  mov bl, [esi]
  mov bl, [eax][ebx]
  test ebx, 16
  jnz @Err
  mov dl, bl
  shl dl, 4
  inc esi

  mov bl, [esi]
  mov bl, [eax][ebx]
  test ebx, 16
  jnz @Err
  or bl, dl
  dec edi
  mov [edi], bl
  inc esi

  dec ecx
  dec ecx
  jnz @LeftBytes

  jmp @Ext
  @Err:
  mov [esp], 0
  @Ext:
  pop eax

  pop edi
  pop esi
  pop edx
  pop ecx
  pop ebx
end
;

// 测试函数,让制定的计算方法多执行几次,以拉开时间差距
function TestHexToInt(HexToIntFunc: THexToIntFunc; var Value: DWORD): DWord
;
var
 
I: Integer
;
begin
 
Result := GetTickCount
;

 
for I := 1 to CalcTimes
do
   
Value := HexToIntFunc(HexStr
);

 
Result := GetTickCount - Result
;
end
;

procedure TForm1.Button1Click(Sender: TObject
);
var
 
Value: DWORD
;
begin
 
Memo1.Lines.Add(Format('HexToInt_tseug0 (%dms).', [TestHexToInt(HexToInt_tseug0, Value
)]));
 
Memo1.Lines.Add(Format('HexToInt_tseug1 (%dms).', [TestHexToInt(HexToInt_tseug1, Value
)]));
 
Memo1.Lines.Add(Format('HexToInt_DoubleWood (%dms).', [TestHexToInt(HexToInt_DoubleWood, Value
)]));
 
Memo1.Lines.Add(Format('HexToInt_beta1 (%dms).', [TestHexToInt(HexToInt_beta1, Value
)]));
 
Memo1.Lines.Add(Format('HexToInt_beta2 (%dms).', [TestHexToInt(HexToInt_beta2, Value
)]));
 
Memo1.Lines.Add('1234'
);
end
;

end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值