Which is the best way to enumerate array elements? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
afe
Posts: 615
Joined: 06 Dec 2018, 04:36

Which is the best way to enumerate array elements?

12 Apr 2019, 03:19

Hello,

Which is the best way to enumerate array elements?

Code: Select all

for index, element in Array
{
    element
}
vs

Code: Select all

i := 1
Loop, % Array.MaxIndex()
{
    Array[i++]
}
Thanks.
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 03:24

it depends on the definition of "the best"..
afe
Posts: 615
Joined: 06 Dec 2018, 04:36

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 03:25

Such as execution speed and resource usage.
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 03:37

I do not know how to assess "resource usage" properly but, speed comparison is pretty simple. You may well know about it. Simply iterate both of them, let's say ten million times.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 03:37

the loop
i stand corrected, see here and here
Last edited by swagfag on 12 Apr 2019, 14:07, edited 1 time in total.
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 04:04

because that is the only practical way to assess the speed easily and reliably
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Which is the best way to enumerate array elements?  Topic is solved

12 Apr 2019, 04:14

Short answer: The normal loop is slower than the for loop.

The for loop has access to the internal data structure and can take one element after the next without performing lookups, but creates overhead by creating an enumerator object.
The normal loop uses lookups for each iteration but doesn't create the initial object.

In practice this means for AHK v1 that if more than 2 entries are present in the object the loop is slower than the for loop.

Some background:
AHK uses a binary search to find the correct value given a specific key. That means it has to compare the number that you give as key to log(n) other numbers to find the value that you look for.
Since the for loop has access to the internal structure it only need 1 step to get to the next entry.
We repeat both of their strategies to get the next entry n times meaning:
Loop: O(n*log n)
for: O(n)
This means that the normal loop is magnitudes worse than the for loop.

In AHK v2 lexikos found a better solution for numerical array access that only requires 1 action to look up the value to an array.
You need to test it for v2.
Recommends AHK Studio
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 04:38

... also, Loop is suitable for Simple Arrays only.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 14:06

Code: Select all

; Example: Demonstrates QueryPerformanceCounter(), which gives more precision than A_TickCount's 10ms.
#NoEnv
SetBatchLines -1
DllCall("QueryPerformanceFrequency", "Int64*", freq)

elements := Round(1.0e7)
Array := []
Array.SetCapacity(elements)
Loop % elements
	Array.Push(A_Index)

DllCall("QueryPerformanceCounter", "Int64*", CounterBefore)
Loop % Array.Count()
	element := Array[A_Index]
DllCall("QueryPerformanceCounter", "Int64*", CounterAfter)
MsgBox % "Loop Elapsed QPC time is " . (CounterAfter - CounterBefore) / freq * 1000 " ms" ; 1400ms



DllCall("QueryPerformanceCounter", "Int64*", CounterBefore)
for index, element in Array
{
	
}
DllCall("QueryPerformanceCounter", "Int64*", CounterAfter)
MsgBox % "ForEach Elapsed QPC time is " . (CounterAfter - CounterBefore) / freq * 1000 " ms" ; 400ms
and the v2 time i got for Loop was 800ms, whereas foreach stayed at 400ms
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 20:02

Some guy's result
Loop loop 1400 ms
For loop 400 ms

Other guy's result
Loop loop 1500 ms
For loop 1900 ms

Code: Select all

DllCall("QueryPerformanceFrequency", "Int64*", freq)
elements := Round(1.0e7)
Array := []
Array.SetCapacity(elements)
Loop % elements
	Array.Push(A_Index)
DllCall("QueryPerformanceCounter", "Int64*", CounterBefore)
Loop % Array.Count()
	myElement := Array[A_Index]
DllCall("QueryPerformanceCounter", "Int64*", CounterAfter)
MsgBox % "Loop Elapsed QPC time is " (CounterAfter - CounterBefore) / freq * 1000 " ms"  ;  1553 ms
DllCall("QueryPerformanceCounter", "Int64*", CounterBefore)
for index, element in Array
	myElement := Array[index]
DllCall("QueryPerformanceCounter", "Int64*", CounterAfter)
MsgBox % "ForEach Elapsed QPC time is " (CounterAfter - CounterBefore) / freq * 1000 " ms"  ;  1962 ms
it depends on the definition of "the best".. again..
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 21:04

Klarion wrote:
12 Apr 2019, 20:02
Some guy's result
Loop loop 1400 ms
For loop 400 ms

Other guy's result
Loop loop 1500 ms
For loop 1900 ms
Interesting. I also got the result of Loop loop being faster than For loop. This was for AHK v1.

Maybe there is some other explanation, than what was stated, that decides how well For loop does. As in For loop is faster in AHK v2, but slower in AHK v1. That, or some other factors are at play.
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

12 Apr 2019, 21:16

feels like marathon racing between Michael Jeffrey Jordan and Usain St. Leo Bolt
just silly from the very beginning
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 02:44

why are u doing myElement := Array[index] inside the forloop?????
element already contains the element. theres no need to be fetching it twice
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 04:58

for millions years of AHK history
Loop had been the only loop
as you know well, For loop emerged quite recently
Both of them are just different stuffs

I have tried a little bit to make it fair superficially

never mind
nothing is serious in this post

Bye
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 05:19

There is no other explination than the code simply being wrong here. :P
Recommends AHK Studio
Klarion
Posts: 176
Joined: 26 Mar 2019, 10:02

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 05:39

yes it is quite like to compare between compile language and script language
both are different
noting is wrong
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 05:47

Are you like trolling?
To conclude this topic: The for loop is magnitudes faster.
Recommends AHK Studio
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 06:00

@nnnik: He/she's also known as IMEime.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Which is the best way to enumerate array elements?

13 Apr 2019, 06:05

look. this code retrieves every element once:

Code: Select all

Loop % Array.Count()
	myElement := Array[A_Index]
then, this code retrieves every element two times. for index, element in Array the first time, and myElement := Array[index] a second time:

Code: Select all

for index, element in Array
	myElement := Array[index]
u cant bench them together as though theyre identical

also, the forloop was added nearly a decade ago. so not that recently

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: haomingchen1998, robodesign and 252 guests