Page 1 of 2
We have a Mid replacement. Any thoughts on FindString ?
Posted: Sun Oct 22, 2006 11:21 pm
by yrret
I was really impressed with the speed gain with the FMid2 (Mid replacement) program. I found it consistently 10 time faster
then when using Mid. I was wondering with the expertise out there, if any one ever thought about, or think it's possible to improve the
FindString(String$, StringToFind$, StartPosition) speed?
That is one command I use alot, and it does slow the running program down when you use it alot.
Posted: Mon Oct 23, 2006 8:49 am
by jqn
And StringField(String$, Index, Delimiter$) ?
And ReplaceString(String$, StringToFind$, StringToReplace$ [, Mode [, StartPosition]]) ?
Both commands are also used alot.
Posted: Mon Oct 23, 2006 11:16 am
by wilbert
The fastest way would be to use asm with sse functions.
Using C functions already makes a significant difference.
Turn off debugging for a fair comparisson.
Code: Select all
Global hMSVCRT.l = GetModuleHandle_("msvcrt.dll")
Global fStrStr.l = GetProcAddress_(hMSVCRT, "strstr")
Global fStrLen.l = GetProcAddress_(hMSVCRT, "strlen")
Procedure.l FindString2_(*String.l, *StringToFind.l, StartPosition.l)
If StartPosition <= CallCFunctionFast(fStrLen, *String)
If StartPosition < 2
StartPosition = 0
Else
StartPosition - 1
EndIf
Protected StrPos.l = CallCFunctionFast(fStrStr, *String + StartPosition, *StringToFind)
If StrPos
StrPos + 1 - *String
EndIf
ProcedureReturn StrPos
Else
ProcedureReturn 0
EndIf
EndProcedure
Macro FindString2(String, StringToFind, StartPosition)
FindString2_(@String, @StringToFind, StartPosition)
EndMacro
#Tries = 10000000
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString("The quick brown fox jumped over the lazy dog","lazy",7)
Next
MessageRequester("", Str(GetTickCount_()-time))
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString2("The quick brown fox jumped over the lazy dog","lazy",7)
Next
MessageRequester("", Str(GetTickCount_()-time))
Posted: Mon Oct 23, 2006 11:51 am
by KarLKoX
Fixed code :
Code: Select all
Global hMSVCRT.l = LoadLibrary_("msvcrt.dll")
Global fStrStr.l = GetProcAddress_(hMSVCRT, "strstr")
Global fStrLen.l = GetProcAddress_(hMSVCRT, "strlen")
Procedure.l FindString2_(*String.l, *StringToFind.l, StartPosition.l)
If StartPosition <= CallCFunctionFast(fStrLen, *String)
If StartPosition < 2
StartPosition = 0
Else
StartPosition - 1
EndIf
Protected StrPos.l = CallCFunctionFast(fStrStr, *String + StartPosition, *StringToFind)
If StrPos
StrPos + 1 - *String
EndIf
ProcedureReturn StrPos
Else
ProcedureReturn 0
EndIf
EndProcedure
Macro FindString2(String, StringToFind, StartPosition)
FindString2_(@String, @StringToFind, StartPosition)
EndMacro
#Tries = 10000000
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString("The quick brown fox jumped over the lazy dog","lazy",7)
Next
first = GetTickCount_()-time
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString2("The quick brown fox jumped over the lazy dog","lazy",7)
Next
second = GetTickCount_()-time
MessageRequester("", "PureBasic : " + Str(first) + Chr(13) + "MSVCRT : " + Str(second) )
Bench result :
PB ~ 1906
MSCVRT ~ 1140
Posted: Mon Oct 23, 2006 12:03 pm
by netmaestro
Still crashing here..
Posted: Mon Oct 23, 2006 12:55 pm
by wilbert
It doens't crash on my computer so it's hard for me to fix.
Maybe it'll help to use prototypes. I haven't used those so far since I don't know exactly how to use them.
Posted: Mon Oct 23, 2006 12:59 pm
by freak
Using prototypes is a tiny bit faster than Call(C)FunctionFast.
Posted: Mon Oct 23, 2006 1:06 pm
by traumatic
just for the sake of completeness...
Code: Select all
Global hMSVCRT.l = LoadLibrary_("msvcrt.dll")
Global fStrStr.l = GetProcAddress_(hMSVCRT, "strstr")
Global fStrLen.l = GetProcAddress_(hMSVCRT, "strlen")
PrototypeC strstr(a,b) : PrototypeC strlen(a)
Global strstr.strstr = GetProcAddress_(hMSVCRT, "strstr")
Global strlen.strlen = GetProcAddress_(hMSVCRT, "strlen")
Procedure.l FindString2_(*String.l, *StringToFind.l, StartPosition.l)
If StartPosition <= CallCFunctionFast(fStrLen, *String)
If StartPosition < 2
StartPosition = 0
Else
StartPosition - 1
EndIf
Protected StrPos.l = CallCFunctionFast(fStrStr, *String + StartPosition, *StringToFind)
If StrPos
StrPos + 1 - *String
EndIf
ProcedureReturn StrPos
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.l FindString3_(*String.l, *StringToFind.l, StartPosition.l)
If StartPosition <= Strlen(*String)
If StartPosition < 2
StartPosition = 0
Else
StartPosition - 1
EndIf
Protected StrPos.l = Strstr(*String + StartPosition, *StringToFind)
If StrPos
StrPos + 1 - *String
EndIf
ProcedureReturn StrPos
Else
ProcedureReturn 0
EndIf
EndProcedure
Macro FindString2(String, StringToFind, StartPosition)
FindString2_(@String, @StringToFind, StartPosition)
EndMacro
Macro FindString3(String, StringToFind, StartPosition)
FindString3_(@String, @StringToFind, StartPosition)
EndMacro
#Tries = 10000000
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString("The quick brown fox jumped over the lazy dog","lazy",7)
Next
first = GetTickCount_()-time
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString2("The quick brown fox jumped over the lazy dog","lazy",7)
Next
second = GetTickCount_()-time
time = GetTickCount_()
For I = 0 To #Tries
p.l = FindString3("The quick brown fox jumped over the lazy dog","lazy",7)
Next
third = GetTickCount_()-time
MessageRequester("", "PureBasic : " + Str(first) + Chr(13) + "MSVCRT : " + Str(second) + Chr(13) + "MSVCRT / Proto : " + Str(third) )
Posted: Mon Oct 23, 2006 1:48 pm
by wilbert
Thanks Traumatic !
That helps
The prototype way is not only faster but also the code looks cleaner.
Posted: Mon Oct 23, 2006 2:48 pm
by netmaestro
@Traumatic,
That works here, no crashing. Debugger off is showing MSVCRT around half the proctime of native PB with proto, 60% without. Thanks for posting.
Posted: Tue Oct 24, 2006 3:36 am
by yrret
Thank you very much Traumatic !
That will really help others speed up programs
that need to use that code alot like I do.

Posted: Tue Oct 24, 2006 11:50 am
by SoulReaper
Wow thats Great
on xp1800 cpu
Pure Basic : 3515 <--- Winner

MSVCRT : 11375
MSVCRT Proto : 11657
@Traumatic
Thankyou for this Excellent Work...
I wonder where Microsoft went wrong
I love the speed of Pure Basic

Posted: Tue Oct 24, 2006 12:16 pm
by traumatic
Hmm... wonder why everyone thanks ME since I only showed how to use prototypes...
Well, you're welcome anyway

What is FMid2?
Posted: Wed Oct 25, 2006 3:11 pm
by Mikro
Sorry in advance if this question is really, really dumb.
What is FMid2 and where is it?
I just don't understand when the title mentions that we have a MID replacement? Where do you get this replacement?
Thanks a lot.
M.
Re: What is FMid2?
Posted: Wed Oct 25, 2006 3:48 pm
by traumatic