This is just a speed test example, it it NOT production safe as the routine has no maxlen limit, fixed/auto/user specified.
Also, interestingly enough PB's Len() is always faster here.
The source is based on the one above, but improved for more reliable test result. (minimum overhead for the loop, uniform loops, as static loops as possible to allow the CPU to kick in caching/optimization.)
My results where (3 seperate runs, 20% existing system load, AMD Athlon XP 1.85Ghz):
STRLen() 71chars: 4036ms
Len() 71chars: 2343ms
STRLen() 1chars: 3626ms
Len() 1chars: 941ms
STRLen() 71chars: 3995ms
Len() 71chars: 2303ms
STRLen() 1chars: 3725ms
Len() 1chars: 922ms
STRLen() 71chars: 3956ms
Len() 71chars: 2273ms
STRLen() 1chars: 3495ms
Len() 1chars: 882ms
Code: Select all
DataSection
STRINGTBL:
Data.l 0, 0, 0, $FF
Data.l 0, $FFFF, 0, $FFFFFF
Data.l 0, $FFFFFFFF, $FF, $FFFFFFFF
Data.l $FFFF, $FFFFFFFF, $FFFFFF, $FFFFFFFF
EndDataSection
Procedure.l STRLen(*pString)
MOV eax, *pString
!pxor mm1, mm1
!MOV ecx, eax
!MOV edx, eax
!AND ecx, -8
!AND eax, 7
!movq mm0, [ecx]
!por mm0, [l_stringtbl+eax*8]
!@@:
!ADD ecx, 8
!pcmpeqb mm0, mm1
!packsswb mm0, mm0
!movd eax, mm0
!movq mm0, [ecx]
!TEST eax, eax
!JZ @b
!BSF eax, eax
!SHR eax, 2
!LEA ecx, [ecx+eax-8]
!SUB ecx, edx
!MOV eax, ecx
!emms
ProcedureReturn
EndProcedure
beta1.s = "We are checking the speed of StrLen() for strings larger than 12 chars!"
beta2.s = "P"
StartTime.l=0
EndTime.l=0
testlen.l=0
Delay(1000)
StartTime = GetTickCount_()
For i = 0 To 10000000
testlen=STRLen(@beta1)
Next
EndTime=GetTickCount_()
Debug "STRLen() "+Str(testlen)+"chars: "+Str(EndTime-StartTime)+"ms"
StartTime.l=0
EndTime.l=0
testlen.l=0
Delay(1000)
StartTime = GetTickCount_()
For i = 0 To 10000000
testlen=Len(beta1)
Next
EndTime=GetTickCount_()
Debug "Len() "+Str(testlen)+"chars: "+Str(EndTime-StartTime)+"ms"
StartTime.l=0
EndTime.l=0
testlen.l=0
Delay(1000)
StartTime = GetTickCount_()
For i = 0 To 10000000
testlen=STRLen(@beta2)
Next
EndTime=GetTickCount_()
Debug "STRLen() "+Str(testlen)+"chars: "+Str(EndTime-StartTime)+"ms"
StartTime.l=0
EndTime.l=0
testlen.l=0
Delay(1000)
StartTime = GetTickCount_()
For i = 0 To 10000000
testlen=Len(beta2)
Next
EndTime=GetTickCount_()
Debug "Len() "+Str(testlen)+"chars: "+Str(EndTime-StartTime)+"ms"
End
Yes it may seem a odd way to do it,
but remember. the For Next itself as well as the StartTime and EndTime
is all part of the timing so those need to be as simple and minimalistic as possible too.
I always make speed tests in a similar way to this on stuff.
The 1 sec delay is to allow the cpu and system to breathe.