If statement functions speedtest

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

If statement functions speedtest

08 Apr 2019, 03:25

Hi there!

I was trying to determine if stuff that happens after an untrue part of the if-statement, is still read and therefore slow down the runtime of a script. For example:

Code: Select all

x=1
if (x=1)
	y=a
else if (x=2)	; not true, does this get read?
	y=b		; does this get read?
The functions I test the runtime of and the functions I'm using to calculate the runtime are pasted below. The results are getting pasted in Excel.
Spoiler
The runtime results are shown below. It seems that AHK still reads the untrue if-statements and its contents.
However, what I find strange is that Function 3: else if (x=2)
y=a
takes almost twice as long as Function 2: else if (x=2)
if (x!=3)
if(z=2)
y=b

Isn't that strange since Function 2 has way more contents than Function 3?
AHKForumTest.png
AHKForumTest.png (3.04 KiB) Viewed 3247 times
Last edited by AviationGuy on 10 Apr 2019, 02:45, edited 2 times in total.
swagfag
Posts: 6212
Joined: 11 Jan 2017, 17:59

Re: Strange function runtime behaviour

08 Apr 2019, 04:35

what results? all i see here are code fragments and unsubstantiated claims. provide an exact minimal working script for others to try out. otherwise, might as well sit down and compare kiwis and pomegranates
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: Strange function runtime behaviour

08 Apr 2019, 05:02

Yeah well, I forgot to post the whole script, that should've been in the 'spoiler' part. Sorry, my bad.
But when I wanted to add it I saw that I had a typo somewhere...
It works as expected now and it seems that untrue if-statements aren't read and won't increase the runtime.
This are the functions I tested the runtime of.

Code: Select all

	
	; function 1
	Speed1()
	NextCol=0
	Loop 1000000	; loop 1.000.000 times
	{
		if (x=1){
			y = a
		}
	}
	Speed2x()

	; function 2
	Speed1()
	NextCol=0
	Loop 1000000				; loop 1.000.000 times
	{
		If (x=1){
			y=b
		}
		else if (x=2)
			if (x!=3)
				if(z=2)
					y=b
		else if (x=3)
			if (x!=4)
				if(z=3)
					y=b
		else if (x=4)
			if (x!=5)
				if(z=4)
					y=b
	}
	Speed2x()

	; function 3
	Speed1()
	NextCol=1
	Loop 1000000	; loop 1.000.000 times
	{
		If (x=1){
			y=a
		}
		else if (x=2)
			y=a
		else if (x=3)
			y=a
		else if (x=4)
			y=a
	}
	Speed2x()
And this are the results.
  • Function 1 - 249ms
  • Function 2 - 246ms
  • Function 3 - 244ms
swagfag
Posts: 6212
Joined: 11 Jan 2017, 17:59

Re: Strange function runtime behaviour

09 Apr 2019, 12:17

Code: Select all

x:=1               
; 1) -------------------------
if (x=1){ ;<<<<<<<<< evaluated
	y = a ;<<<<<<<<< evaluated
}                  
; 2) -------------------------
If (x=1){ ;<<<<<<<<< evaluated
	y=b ;<<<<<<<<<<< evaluated
}                  
else if (x=2) ;<<<<< evaluated
	if (x!=3) ;<<<<< not
		if(z=2) ;<<< not
			y=b ;<<< not
else if (x=3) ;<<<<< evaluated
	if (x!=4) ;<<<<< not
		if(z=3) ;<<< not
			y=b ;<<< not
else if (x=4) ;<<<<< evaluated
	if (x!=5) ;<<<<< not
		if(z=4) ;<<< not
			y=b ;<<< not
; 3) -------------------------
If (x=1){ ;<<<<<<<<< evaluated
	y=a ;<<<<<<<<<<< evaluated
}                  
else if (x=2) ;<<<<< evaluated
	y=a ;<<<<<<<<<<< not
else if (x=3) ;<<<<< evaluated
	y=a ;<<<<<<<<<<< not
else if (x=4) ;<<<<< evaluated
	y=a ;<<<<<<<<<<< not
; ----------------------------
cases 2 and 3 will be marginally slower on average in the long run
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: Strange function runtime behaviour

09 Apr 2019, 13:04

Yes, I was wrong indeed.
Untrue statements are read and will actually slow down runtime.
I modified the script some more and got some nice results. I loop each ‘function’ 1.000.000 times to get a clear view of the different runtimes and to easily tell the difference between them.
Will post the results tomorrow if I get it done!

Thanks for your time man!
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: Strange function runtime behaviour

10 Apr 2019, 02:44

Well, that is actually not what I tried to test. Cases 2 & 3 are indeed slower for x=1 but when you change x=1 to x=4 and run case 2 & 3 again you'll see that the runtime will be equal. So in that case, the statement: "Untrue conditions won't be read and thus won't slow down runtime" will be true.

***EDIT***
Changed title
lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: If statement functions speedtest

10 Apr 2019, 03:52

Each script is semi-compiled while it is being loaded and syntax-checked.
...
Loops, blocks, IFs, and ELSEs are given the memory addresses of their related jump-points in the script.
Source: Script Performance | AutoHotkey
When a jump is executed, the "current line" pointer is simply changed from one value to another. The intervening lines are irrelevant (they are not read).

"Untrue statements", or statements which are not executed, are not read at runtime. All statements are read into memory when the script loads, and exist there until the program exits. The presence of a statement therefore may affect where other statements are placed in memory. This has unpredictable interaction with other low-level performance factors, such as CPU cache hits/misses.

Benchmarking trivial code, such as simple conditional statements or assignments, is often futile, as execution takes so little time that the effects of those other factors can be significant by comparison. I would suggest benchmarking only when a performance issue actually exists, and to avoid making generalizations based on the results.

Also, I note that SetBatchLines -1 was used nowhere in this thread. With the default settings, the program will sleep every so often and allow other processes or threads more CPU time. You will get roughly half as much CPU time in ideal conditions (no other needy processes), but the timing of the sleep is not exact. Basically, the results will be less predictable and more prone to outside influence.
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

10 Apr 2019, 04:18

Goal
Ok, I will try explaining the reason why I want to test this:
The reason why I'm testing this is because I want to be able to use different versions of functions. I added the version I want to use as the first parameter. I did it like this.

Code: Select all

; ImageSearchFunction (ISF) version definition
version:="v2"
; ISF call
ImageSearchFun(version)

; ISF function
ImageSearchFun(version:="basic", x1:=0, y1:=0, x2:=0, y2:=0, ImageFile:="S:\Path\Image.png"){
	if (version="basic"){
		ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
		Msgbox basic stuff
	}
	else if (version="v1"){
		ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
		Msgbox v1 stuff
	}
	else if (version="v2"){
		ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
		Msgbox v2 stuff
	}
}
Because this will result in a lot of else-if statements I wanted to test if this will slow down the runtime.

Different use of if statement within function speed (x=1)
I've created 5 situations (functions). I predefined x=1 and with the 5 functions I tested, I got the following results. Functions are shown below.

Code: Select all

	; function 1
	Speed1()
	NextCol=0
	Loop 1000000	; loop 1.000.000 times
	{
		y=1	; assign value
	}
	Speed2x()
	
	; function 2	
	Speed1()
	NextCol=0
	Loop 1000000		; loop 1.000.000 times
	{
		If (x=1)	; if x has a value of 1
			y=2	; assign value
	}
	Speed2x()
	
	; function 3
	Speed1()
	NextCol=0
	Loop 1000000	; loop 1.000.000 times
	{
		If (x=0){		; if x has a value of 1
			y=3		; assign value
		}
		else if (x=1)	; else if x has a value of 2
			y=3		; assign variable
		else if (x=2)
			y=3
		else if (x=3)
			y=3
		else if (x=4)
			y=3
	}
	Speed2x()
	
	; function 4
	Speed1()
	NextCol=0
	Loop 1000000				; loop 1.000.000 times
	{
		If (x=0){				; if x has a value of 0
			y=4				; assign value
		}
		else if (x=1){			; else if x has a value of 1
			if (x!=5){		; if x doesn't have a value of 5
				if (z=2){		; if z has a value of 2
					y=4		; assign value
		}}}
		else if (x=2){
			if (x!=5){	
				if (z=2){	
					y=4	
		}}}
		else if (x=3){
			if (x!=5){	
				if (z=2){	
					y=4	
		}}}
		else if (x=4){
			if (x!=5){
				if (z=2){
					y=4
		}}}
	}
	Speed2x()
	
	; function 5
	Speed1()
	NextCol=1
	Loop 1000000			; loop 1.000.000 times
	{
		If (x=0)			; if x has a value of 0
			y=5			; assign value
		If (x=1)			; if x has a value of 1
			y=5			; assign value
		If (x=2)
			y=5
		If (x=3)
			y=5
		If (x=4)
			y=5
	}
	Speed2x()
  • Function 1: 67,45ms
  • Function 2: 175,88ms
  • Function 3: 297,94ms
  • Function 4: 603,92ms
  • Function 5: 597,04ms
Are untrue statements read
Based on this I did some more testing. I wanted to know if untrue else-if statements were read and thus slow down runtime. To check this I predefined x=4 and ran function 3 and 4 again. Results are below
  • Function 3: 606,97ms
  • Function 4: 605,34ms
So my conclusion is that based on my testing, untrue if statements aren't read and will not slow down runtime.

Influence of else-if statements
Finally, I wanted to know if multiple else-if statements will effect the runtime. I ran function 3, 4 and 5 with x=1, x=2, x=3 and x=4.
AHKForumTest.png
AHKForumTest.png (9 KiB) Viewed 3044 times
Results are that AHK slows down about 120ms (depending on size of content of else-if statement) per else-if statement (per 1.000.000 runs). Fun thing is that function 5 which uses separate if statements is faster when the amount of else-if statements is increased so maybe that is the way to go for me.

Response:
Benchmarking trivial code, such as simple conditional statements or assignments, is often futile, as execution takes so little time that the effects of those other factors can be significant by comparison. I would suggest benchmarking only when a performance issue actually exists, and to avoid making generalizations based on the results.
You are completely right. But instead of testing, I want to see if I could track down if the runtime will increase with the use of multiple (else-) if statements. I don't have a change of testing this on my main script yet and therefore wanted to try and find on the influence of (else-) if statements on the runtime. At least, try to get a somewhat reliable result.
Also, I note that SetBatchLines -1 was used nowhere in this thread.
I indeed didn't mention it but I'm using SetBatchLines -1 :)

Thanks for the info @lexikos I appreciated your feedback.
swagfag
Posts: 6212
Joined: 11 Jan 2017, 17:59

Re: If statement functions speedtest

10 Apr 2019, 06:02

stuff
that aint how u do it. first ure doing string comparisons while in the benchmark u were benching numerical comparisons. second i dont even what u assume "untrue elseif statements aren't read" mean, cuz they totally are. if u define version := "v2, if (version="basic") is evaluated, then else if (version="v1") is evaluated and finally else if (version="v2") is evaluated. its only the bodies of untrue elseif statements that arent evaluated, meaning if u keep this function as is, "basic" calls will be on average the fastest in the long run, "v1" calls slower and "v2" calls slower still, ceteris paribus.

chunk this function into 3 new ones, as it should have originally been to begin with, and call them dynamically. it will be marginally slower than calling a function directly, but still faster than this ifelse ladder thingamabob

Code: Select all

version:="v2"
%version%()

basic(x1:=0, y1:=0, x2:=0, y2:=0, ImageFile:="S:\Path\Image.png") {
	ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
	Msgbox basic stuff
}

v1(x1:=0, y1:=0, x2:=0, y2:=0, ImageFile:="S:\Path\Image.png") {
	ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
	Msgbox v1 stuff
}

v2(x1:=0, y1:=0, x2:=0, y2:=0, ImageFile:="S:\Path\Image.png") {
	ImageSearch, FoundX, FoundY, x1, y1, x2, y2, %ImageFile%
	Msgbox v2 stuff
}
btw these optimizations are meaningless. Imagesearch is orders of magnitude slower than a comparison, ure wasting ur time
User avatar
jeeswg
Posts: 6901
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If statement functions speedtest

10 Apr 2019, 06:08

IIRC:

Code: Select all

;slower:
version:="v2"
%version%()

;faster:
version:=Func("v2")
%version%()
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

10 Apr 2019, 06:29

Haha, I like you sir.
Q1
swagfag wrote:
10 Apr 2019, 06:02
that aint how u do it. first ure doing string comparisons while in the benchmark u were benching numerical comparisons. second i dont even what u assume "untrue elseif statements aren't read" mean, cuz they totally are. if u define version := "v2, if (version="basic") is evaluated, then else if (version="v1") is evaluated and finally else if (version="v2") is evaluated. its only the bodies of untrue elseif statements that arent evaluated, meaning if u keep this function as is, "basic" calls will be on average the fastest in the long run, "v1" calls slower and "v2" calls slower still, ceteris paribus.
Yes, the stuff you mentioned is read and evaluated, of course, otherwise, it wouldn't know if the statement corresponds yes or no. But my point is, the body of an 'untrue' else-if statement isn't read and therefore won't slow down runtime.
I understand that when version="basic" the script will run faster than the others because it can stop reading and evaluating the following else-if statements. I found this out in the part Incluence of else-if statements of my previous post:
AviationGuy wrote:
10 Apr 2019, 04:18
Influence of else-if statements
Finally, I wanted to know if multiple else-if statements will effect the runtime. I ran function 3, 4 and 5 with x=1, x=2, x=3 and x=4.
Image of table
Results are that AHK slows down about 120ms (depending on size of content of else-if statement) per else-if statement (per 1.000.000 runs). Fun thing is that function 5 which uses separate if statements is faster when the amount of else-if statements is increased so maybe that is the way to go for me.
Q2
swagfag wrote:
10 Apr 2019, 06:02
chunk this function into 3 new ones, as it should have originally been to begin with, and call them dynamically. it will be marginally slower than calling a function directly, but still faster than this ifelse ladder thingamabob
This is a great idea! Only 1 problem tho... In this way I 'lose' the ability of having a 'main' function which I can change. When I want to change something that all the scripts have, I need to do this manually in everyone with your idea. When I have mine script I can make changes in the ImageSearchFun function and this will change all the following function versions.
swagfag wrote:
10 Apr 2019, 06:02
btw these optimizations are meaningless. Imagesearch is orders of magnitude slower than a comparison, ure wasting ur time
I'm just using ImageSearch as an example.

Looking forward to your reaction ;)
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

10 Apr 2019, 06:30

jeeswg wrote:
10 Apr 2019, 06:08
IIRC:

Code: Select all

;slower:
version:="v2"
%version%()

;faster:
version:=Func("v2")
%version%()
If the idea of @swagfag turns out to be the solution for me I will definitely do it like this, thanks!
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

11 Apr 2019, 08:50

Atm, I'm testing the speed of assigning a value to q with the adaptable function method @swagfag mentioned.
I want to know the time it takes to do this a million times but I can't figure it out. I'm trying to do this, in the same way, as I did with the other functions.

Code: Select all

version:=Func("x1")
Speed1()
	NextCol=1
	Loop 1000000				; loop 1.000.000 times
	{
	%version%()
		
	x1() {
		var=3
	}
	x2() {
		var=3
	}
	x3() {
		var=3
	}
	x4() {
		var=3
	}
	}
Speed2x()
Msgbox % var
I use a msgbox to test if the function actually assigns a value to variable 'var' and I found out that it didn't... This means that the loop doesn't do what I want and that the obtained runtime, therefore, isn't valid.
What am I doing wrong here?
Last edited by AviationGuy on 11 Apr 2019, 08:59, edited 1 time in total.
swagfag
Posts: 6212
Joined: 11 Jan 2017, 17:59

Re: If statement functions speedtest

11 Apr 2019, 08:58

ure posting fragments. what is the value of version? is var global? also idk why u put the functions inside the loop. functions can be defined anywhere... for the most part
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

11 Apr 2019, 09:02

Edited ^^^
Well, this shows a msgbox with 1. So I thought the script above will give a msgbox with 3.

Code: Select all

x:=1
Speed1()
NextCol=0
Loop 1000000	; loop 1.000.000 times
{
	If (x=0){		; if x has a value of 1
		y=1		; assign value
	}
	else if (x=1)	; else if x has a value of 2
		y=1		; assign variable
	else if (x=2)
		y=1
	else if (x=3)
		y=1
	else if (x=4)
		y=1
}
Speed2x()
msgbox % y
swagfag
Posts: 6212
Joined: 11 Jan 2017, 17:59

Re: If statement functions speedtest

11 Apr 2019, 09:06

functions have scope. each var in each of these functions is unique, and also different from the globally defined var. this is why ur msgbox is empty. read about scope in the docs
AviationGuy
Posts: 188
Joined: 17 Jan 2019, 10:13

Re: If statement functions speedtest

11 Apr 2019, 09:29

Ok, thanks. I don't actually want to use the variable so it isn't a problem if the msgbox is empty after the loop. I just wanted to know if it does actually assign the variable.
I tested it with the msgbox within the 'x1' function and the '3' showed up so that means that it assigned the value to the variable 'var' and thus that the runtime is correct for representing that action.

Code: Select all

version:=Func("x1")
Speed1()
	NextCol=1
	Loop 1000000				; loop 1.000.000 times
	{
	%version%()
		
	x1() {
		var=3
	msgbox % var
	}
Speed2x()

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: braunbaer, haomingchen1998, peter_ahk and 198 guests