Thanks for the effort AZJIO, it's almost the same thing and it does the job.
I'm not sure the return flag (0/1) is useful. It does its job whether the string is empty, identical or different.
Your 2nd variant code looks good for the concept but I'm not sure there's any real gain.
Anyway, thanks to both of you, I'm starting to feel a little more comfortable with pointers now
To nitpick, I measured the times with different options (Select vs If, While Wend vs Repeat Until)
Code: Select all
EnableExplicit
Procedure RemoveNonWordChars_WhileWend_Select_If(*c.Character )
If *c = 0 Or *c\c = 0 : ProcedureReturn : EndIf
Protected *c2.Character = *c
Macro _KeepChar_()
If *c2 <> *c
*c2\c = *c\c
EndIf
*c2 + SizeOf(Character)
EndMacro
While *c\c
Select *c\c
Case '0' To '9'
_KeepChar_()
Case 'a' To 'z'
_KeepChar_()
Case 'A' To 'Z'
_KeepChar_()
Case '_'
_KeepChar_()
EndSelect
*c + SizeOf(Character)
Wend
If *c <> *c2
*c2\c = 0
EndIf
EndProcedure
Procedure RemoveNonWordChars_WhileWend_Select(*c.Character )
If *c = 0 Or *c\c = 0 : ProcedureReturn : EndIf
Protected *c2.Character = *c
Macro _KeepChars_()
*c2\c = *c\c
*c2 + SizeOf(Character)
EndMacro
While *c\c
Select *c\c
Case '0' To '9'
_KeepChars_()
Case 'a' To 'z'
_KeepChars_()
Case 'A' To 'Z'
_KeepChars_()
Case '_'
_KeepChars_()
EndSelect
*c + SizeOf(Character)
Wend
*c2\c = 0
EndProcedure
Procedure RemoveNonWordChars_WhileWend_If(*c.Character )
If *c = 0 Or *c\c = 0 : ProcedureReturn : EndIf
Protected *c2.Character = *c
While *c\c
If ((*c\c >= '0' And *c\c <= '9') Or (*c\c >= 'a' And *c\c <= 'z') Or (*c\c >= 'A' And *c\c <= 'Z') Or *c\c = '_')
If *c <> *c2
*c2\c = *c\c
EndIf
*c2 + SizeOf(Character)
EndIf
*c + SizeOf(Character)
Wend
If *c <> *c2
*c2\c = 0
EndIf
EndProcedure
Procedure RemoveNonWordChars_RepeatUntil_If(*c.Character )
If *c = 0 Or *c\c = 0 : ProcedureReturn : EndIf
Protected *c2.Character = *c
Repeat
If ((*c\c >= '0' And *c\c <= '9') Or (*c\c >= 'a' And *c\c <= 'z') Or (*c\c >= 'A' And *c\c <= 'Z') Or *c\c = '_')
If *c <> *c2
*c2\c = *c\c
EndIf
*c2 + SizeOf(Character)
EndIf
*c + SizeOf(Character)
Until Not *c\c
If *c <> *c2
*c2\c = 0
EndIf
EndProcedure
Define MyStr$
CompilerIf Not #PB_Compiler_Debugger
Define I, s1, s2, s3, s4, Loop = 1000000
MyStr$ = "@abc~123-ABC\_*,!wt=-()ty3456!_#$%*àçéèÉÊ(){}[]XYZ"
s1 = ElapsedMilliseconds()
For I = 1 To Loop
RemoveNonWordChars_WhileWend_Select_If(@MyStr$)
Next I
s1 = ElapsedMilliseconds() - s1
MyStr$ = "@abc~123-ABC\_*,!wt=-()ty3456!_#$%*àçéèÉÊ(){}[]XYZ"
s2 = ElapsedMilliseconds()
For I = 1 To Loop
RemoveNonWordChars_WhileWend_Select(@MyStr$)
Next I
s2 = ElapsedMilliseconds() - s2
MyStr$ = "@abc~123-ABC\_*,!wt=-()ty3456!_#$%*àçéèÉÊ(){}[]XYZ"
s3 = ElapsedMilliseconds()
For I = 1 To Loop
RemoveNonWordChars_WhileWend_If(@MyStr$)
Next I
s3 = ElapsedMilliseconds() - s3
MyStr$ = "@abc~123-ABC\_*,!wt=-()ty3456!_#$%*àçéèÉÊ(){}[]XYZ"
s4 = ElapsedMilliseconds()
For I = 1 To Loop
RemoveNonWordChars_RepeatUntil_If(@MyStr$)
Next I
s4 = ElapsedMilliseconds() - s4
MessageRequester("Info", ~"RemoveNonWordChars_WhileWend_Select_If: \t" + Str(s1) + ~"ms\nRemoveNonWordChars_WhileWend_Select: \t" + Str(s2) + ~"ms\nRemoveNonWordChars_WhileWend_If: \t" + Str(s3) + ~"ms\nRemoveNonWordChars_RepeatUntil_If: \t" + Str(s4) + "ms")
CompilerElse
MyStr$ = "@abc~123-ABC\_*,!wt=-()ty3456!_#$%*àçéèÉÊ(){}[]XYZ"
Debug MyStr$
RemoveNonWordChars_WhileWend_Select_If(@MyStr$)
Debug MyStr$
CompilerEndIf
Result:
RemoveNonWordChars_WhileWend_Select_If: 48ms
RemoveNonWordChars_WhileWend_Select: 54ms
RemoveNonWordChars_WhileWend_If: 63ms
RemoveNonWordChars_RepeatUntil_If: 65ms
Do you have ~ same results ? here:
Tested If *c <> *c2 before before moving *c2\c = *c\c is a little faster
With multiple ranges, Select Case '0' To '9', 'a' To 'z',... is a little faster than If (*c\c >= '0' And *c\c <= '9') Or (*c\c >= 'a' And *c\c <= 'z') Or...
While *c\c : Wend is a little faster than Repeat : Until Not *c\c