RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Guest

RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

19 Mar 2017, 11:34

Code: Select all

gui, wait: add, text, w200 h100 center 0x200, Wait
gui, wait: show

loop, 1000000
Text .= "ABC"

Start := A_TickCount

TempText := RegExReplace(Text, "A", "#")
TempText := RegExReplace(TempText, "B", "#")
TempText := RegExReplace(TempText, "C", "#")

gui, add, edit, w300 h200 +Hscroll +HwndTempControlId,
ControlSetText , , % A_TickCount - Start " milliseconds (3 Function Calls)`r`n" TempText, % "ahk_id" TempControlId

Start := A_TickCount

TempText := RegExReplace(Text, "A|B|C", "#")

gui, add, edit, w300 h200 x+5 +Hscroll +HwndTempControlId,
ControlSetText , , % A_TickCount - Start " milliseconds (1 Function Call _ "" | "" in use)`r`n" TempText, % "ahk_id" TempControlId

gui, wait: destroy
gui, show, , RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option

return

guiclose:
waitguiclose:
exitapp
In my system, "Multiple Function Calls" proved to be faster than using vertical bar "|" alternatives option

Another question is, if the RegExReplace is called 3 Times, as shown in the example below, does it mean that the text will be analyzed 3 times too?

TempText := RegExReplace(Text, "A", "#")
TempText := RegExReplace(TempText, "B", "#")
TempText := RegExReplace(TempText, "C", "#")

and what about using vertical bar "|" instead as shown below, will the text be analyzed 3 times or just 1 time?

TempText := RegExReplace(Text, "A|B|C", "#")
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

19 Mar 2017, 11:56

That is actually an interesting question:
Calling the function three times will lead to the text being parsed three times.
Calling it once with a more complex Needle only leads to the whole string being parsed once, but with a more complex search algorythm.
In any case it is prefereable to use the first Version since you don't actually need RegEx for the first ( use StrReplace instead ).
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

19 Mar 2017, 12:23

That is not a very good way to measure. The three calls seems slightly quicker though.

Related, but maybe not applicable in this case, see the S option for RegEx.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

19 Mar 2017, 13:39

@Guest. Interesting.
@Helgef. Did you have any better ideas for measuring apart from using QPC? Or repeating D, i.e. needles not in the haystack?
I had been planning to do some replace A-Z, StrReplace/RegExReplace tests. I.e. 26 v. 1 replacements out of interest.

Code: Select all

q:: ;speed tests on StrReplace/RegExReplace (ABC)
vNum := 5000000
vText := ""
VarSetCapacity(vText, vNum*2*3)
Loop, % vNum
	;vText .= "ABC"
	vText .= "DDD"

;vMode := ""
vMode := "QPC"

StringCaseSense, On
vCount := JEE_TickCount(vMode)
vTemp := StrReplace(vText, "A", "#")
vTemp := StrReplace(vTemp, "B", "#")
vTemp := StrReplace(vTemp, "C", "#")
vCount1 := JEE_TickCount(vMode) - vCount

StringCaseSense, Off
vCount := JEE_TickCount(vMode)
vTemp := StrReplace(vText, "A", "#")
vTemp := StrReplace(vTemp, "B", "#")
vTemp := StrReplace(vTemp, "C", "#")
vCount2 := JEE_TickCount(vMode) - vCount

vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, "A", "#")
vTemp := RegExReplace(vTemp, "B", "#")
vTemp := RegExReplace(vTemp, "C", "#")
vCount3 := JEE_TickCount(vMode) - vCount

vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, "i)A", "#")
vTemp := RegExReplace(vTemp, "i)B", "#")
vTemp := RegExReplace(vTemp, "i)C", "#")
vCount4 := JEE_TickCount(vMode) - vCount

vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, "A|B|C", "#")
vCount5 := JEE_TickCount(vMode) - vCount

vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, "i)A|B|C", "#")
vCount6 := JEE_TickCount(vMode) - vCount

vOutput := ""
Loop, 6
	vOutput .= vCount%A_Index% " "
MsgBox % Clipboard := RTrim(vOutput)
Return

;==================================================

JEE_TickCount(vMode="")
{
if (vMode="")
	Return A_TickCount
if (vMode="QPC")
{
	DllCall("QueryPerformanceCounter", Int64P,vCount)
	Return vCount
}
Return
}

;==================================================

;needle 5000000 lots of ABC
;some results (QPC):
;913856 1081982 2973816 3079294 3273802 3288657
;939184 1079271 2984285 3055107 3258863 3283956
;900688 1101780 2959792 3048761 3260854 3312888
;903530 1081178 3235776 3472521 3260842 3257736
;911640 1071298 2969797 3042706 3251162 3277091
;some results (TC):
;375 468 1279 1326 1388 1389
;390 452 1280 1310 1388 1404
;375 468 1263 1311 1404 1404
;390 453 1341 1342 1388 1404
;374 468 1264 1326 1404 1404

;needle 5000000 lots of DDD
;some results (QPC):
;241944 158816 154808 168322 1892367 1865977
;237268 164055 156015 164801 1956564 1943093
;275679 189225 177818 197927 1864363 1978192
;281677 156818 188495 176463 2155254 1777502
;236211 162478 162719 196326 1963935 1880207
;some results (TC):
;110 78 62 78 764 874
;109 78 78 78 827 780
;94 78 62 78 890 795
;93 78 78 78 812 842
;109 78 62 94 889 796

;==================================================
Some tests on a-z:
(I think everything's OK, it's easy to make a silly mistake doing something like this.)

Code: Select all

;q:: ;speed tests on StrReplace/RegExReplace (abcdefghijklmnopqrstuvwxyz)
vNum := 500000
vList := "abcdefghijklmnopqrstuvwxyz", vCharClass := "[a-z]"
vList := "11111111111111111111111111", vCharClass := "[a-z]"
vList := "ABCDEFGHIJKLMNOPQRSTUVWXYZ", vCharClass := "[A-Z]"
vList := "11111111111111111111111111", vCharClass := "[A-Z]"
vText := ""
VarSetCapacity(vText, vNum*2*26)
Loop, % vNum
	vText .= vList

vMode := ""
;vMode := "QPC"

vTemp := vText
StringCaseSense, On
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	StringReplace, vTemp, vTemp, % A_LoopField, % "", % "All"
vCount1 := JEE_TickCount(vMode) - vCount

vTemp := vText
StringCaseSense, Off
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	StringReplace, vTemp, vTemp, % A_LoopField, % "", % "All"
vCount2 := JEE_TickCount(vMode) - vCount

vTemp := vText
StringCaseSense, On
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	vTemp := StrReplace(vTemp, A_LoopField, "")
vCount3 := JEE_TickCount(vMode) - vCount

vTemp := vText
StringCaseSense, Off
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	vTemp := StrReplace(vTemp, A_LoopField, "")
vCount4 := JEE_TickCount(vMode) - vCount

vTemp := vText
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	vTemp := RegExReplace(vTemp, A_LoopField, "")
vCount5 := JEE_TickCount(vMode) - vCount

vTemp := vText
vCount := JEE_TickCount(vMode)
Loop, Parse, vList
	vTemp := RegExReplace(vTemp, "i)" A_LoopField, "")
vCount6 := JEE_TickCount(vMode) - vCount

vTemp := vText
vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, vCharClass, "")
vCount7 := JEE_TickCount(vMode) - vCount

vTemp := vText
vCount := JEE_TickCount(vMode)
vTemp := RegExReplace(vText, "i)" vCharClass, "")
vCount8 := JEE_TickCount(vMode) - vCount

vOutput := ""
Loop, 8
	vOutput .= vCount%A_Index% " "
MsgBox % Clipboard := RTrim(vOutput)
Return

;==================================================

;[haystack][needles] (tick counts)
;[abcdefghijklmnopqrstuvwxyz][a-z]
;593 561 608 530 1326 1420 1014 998
;593 561 608 546 1342 1419 1014 998
;608 592 733 624 1326 1420 1014 1014
;[11111111111111111111111111][a-z]
;94 188 94 188 967 968 312 312
;109 188 94 188 967 983 297 297
;109 203 109 187 1029 967 312 312
;[ABCDEFGHIJKLMNOPQRSTUVWXYZ][A-Z]
;609 561 593 546 1357 1404 1045 1045
;624 561 593 546 1326 1404 1014 998
;608 562 624 561 1404 1467 1045 1046
;[11111111111111111111111111][A-Z]
;93 187 109 172 999 967 296 296
;109 187 93 187 952 967 312 312
;94 187 94 187 936 983 312 312

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

20 Mar 2017, 11:08

@jeeswg, I don't think it is a good idea to include the gui operations in the measurements.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegExReplace - Multiple Function calls VS Vertical bar "|" Alternatives Option, Which one is faster?

21 Mar 2017, 21:36

@Helgef. Yeah, I couldn't tell what you were referring to in: 'That is not a very good way to measure.'

The inclusion of Gui commands *within* the start/end of the 'stopwatch' period is a little surprising, but the script and idea are good.

Btw have you ever benefited from the S option?
Regular Expressions (RegEx) - Quick Reference
https://autohotkey.com/docs/misc/RegEx-QuickRef.htm
Studies the pattern to try improve its performance.

@Guest. I wonder what made you suspicious about the RegEx speeds!

An old function I wrote, to replace letters, used StrReplace, I'd replaced it with a call to RegExReplace, but I thought that at some point I should double-check the speeds. I'm pretty sure I saw somewhere on the forum/documentation, a warning that RegEx can be slow. Although I think I'd also heard that Loop can be a bit slow.

Surprising results, from above, repeated here:

StringReplace CS/CI (26 replacements)
StrReplace CS/CI (26 replacements)
RegExReplace CS/CI (26 replacements)
RegExReplace CS/CI (1 replacement)

Code: Select all

;[haystack][needles] (tick counts)
;[abcdefghijklmnopqrstuvwxyz][a-z]
;593 561 608 530 1326 1420 1014 998
;593 561 608 546 1342 1419 1014 998
;608 592 733 624 1326 1420 1014 1014
;[11111111111111111111111111][a-z]
;94 188 94 188 967 968 312 312
;109 188 94 188 967 983 297 297
;109 203 109 187 1029 967 312 312
;[ABCDEFGHIJKLMNOPQRSTUVWXYZ][A-Z]
;609 561 593 546 1357 1404 1045 1045
;624 561 593 546 1326 1404 1014 998
;608 562 624 561 1404 1467 1045 1046
;[11111111111111111111111111][A-Z]
;93 187 109 172 999 967 296 296
;109 187 93 187 952 967 312 312
;94 187 94 187 936 983 312 312
[hmm, interesting]
Acquiring high-resolution time stamps (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: doodles333 and 338 guests