procedure _LStrDelete{ var s : AnsiString; index, count : Integer }; asm { EAX Pointer to s } { EDX index } { ECX count } PUSH EBX PUSH ESI PUSH EDI MOV EBX,EAX MOV ESI,EDX MOV EDI,ECX CALL UniqueString MOV EDX,[EBX] TEST EDX,EDX { source already empty: nothing to do } JE @@exit MOV ECX,[EDX-skew].StrRec.length { make index 0-based, if not in [0 .. Length(s)-1] do nothing } DEC ESI JL @@exit CMP ESI,ECX JGE @@exit { limit count to [0 .. Length(s) - index] } TEST EDI,EDI JLE @@exit SUB ECX,ESI { ECX = Length(s) - index } CMP EDI,ECX JLE @@1 MOV EDI,ECX @@1: { move length - index - count characters from s+index+count to s+index } SUB ECX,EDI { ECX = Length(s) - index - count } ADD EDX,ESI { EDX = s+index } LEA EAX,[EDX+EDI] { EAX = s+index+count } CALL Move { set length(s) to length(s) - count } MOV EDX,[EBX] MOV EAX,EBX MOV EDX,[EDX-skew].StrRec.length SUB EDX,EDI CALL _LStrSetLength @@exit: POP EDI POP ESI POP EBX end; Delete 函数中,有这两句:CALL Move和CALL_LstrSetLength。其中Move函数是将一个内存块拷贝到另一个地址,LstrSetLength函数将改变字符串的长度,其中也有对内存进行分配的代码。这些对内存进行操作的函数都是极其消耗CPU运行时间的,所以Delete函数也是一个极其消耗CPU运行时间的函数。为了尽量避免使用这些函数,我对自定义函数RightPos进行了改写。 修改后不再使用Delete及Pos函数,直接通过指针对内存操作,提高了效率。 function RightPosEx(const Substr,S: string): Integer; var iPos: Integer; TmpStr:string; i,j,len: Integer; PCharS,PCharSub:PChar; begin PCharS:=PChar(s); //将字符串转化为PChar格式 PCharSub:=PChar(Substr); Result:=0; len:=length(Substr); for i:=0 to length(S)-1 do begin for j:=0 to len-1 do begin if PCharS[i+j]<>PCharSub[j] then break; end; if j=len then Result:=i+1; end; 请看第一句PCharS:=PChar(s),它的作用是将Delphi字符串强制转化为PChar 格式(PChar 是Windows中使用的标准字符串,不包含长度信息,使用0为结束标志),并得到指向PChar字符串的指针PcharS。 下面就要对自定义函数的运行时间进行测量,为了提高测量的精度,减小随机性,我们计算重复10000次所需的时间。代码如下: var i,len,iPos: Integer; PerformanceCount1,PerformanceCount2,Count:int64; begin len:=10000; //重复次数 QueryPerformanceCounter(PerformanceCount1);//开始计数 for i:=0 to len-1 do begin iPos:=RightPos(’12’,Edit1.Text); //被测试的函数 end; QueryPerformanceCounter(PerformanceCount2); //结束计数 Count:=(PerformanceCount2-PerformanceCount1); Label1.Caption:=inttostr(iPos)+’ time=’+inttostr(Count); End;
| | |