HexToInt的几个函数速度比较
2005-04-21 09:51
381 查看
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.
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.
相关文章推荐
- 关于自定义tableviewcell的注意点以及用到的几个比较有用的函数
- 今天总结了几个常用函数比较相信对初学者有用?
- C++中的模板比较容易混淆的几个概念:类模板和类成员模板以及函数模板
- JQuery 中比较有趣的几个函数
- php 几个比较实用的函数
- JavaScript 数组几个比较有用的函数
- Jquery几个比较实用,但又让很多人忽略的几个函数
- MFC 的几个常用函数,用来计算文件大小,下载速度,转换时间的
- php几个比较高级的函数
- PHP获取当前路径的几个函数的比较
- UC编程:通过fwrite()和write()比较标准库函数和系统调用的速度
- Windows上几个常用的获取时间戳函数的效率比较
- 几个搜索引擎收录博客速度的比较
- C的几个函数安全性比较
- php 几个比较实用的函数
- MFC 的几个常用函数,用来计算文件大小,下载速度,转换时间的
- 查看运行时间函数--比较运行速度
- 以前用得比较少的几个函数:fmod floor ceil......
- Windows上几个获取时间戳函数的效率比较
- 几个字符串输入函数比较