"Smart" For?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

"Smart" For?

Post by Piero »

Code: Select all

k=2
For i=1 To k
   Debug i
   k-1 ; exits For earlier
Next

s.s="N2"
For i=1 To Len(s)
   Delay(1) ; s unchanged
Next
Is the compiler "smart" enough to make it calculate Len(s) only once?
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: "Smart" For?

Post by BarryG »

It's by design (previous discussion on this forum somewhere). The Len() bit is recalculated with every loop iteration, for times when it can change by the coder (which is a valid use case). But if it's a static value that never changes, then for speed it's better to assign it to a variable and use the variable in the "For" statement.
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: "Smart" For?

Post by Piero »

Yep, thanks! I just tested it:

Code: Select all

For i=1 To 10000
   s.s+"."
Next
n=Len(s)

StartTime.q = ElapsedMilliseconds()
For i=1 To Len(s)
   Delay(1)
Next
Debug ElapsedMilliseconds() - StartTime ; 11650

StartTime = ElapsedMilliseconds()
For i=1 To n
   Delay(1)
Next
Debug ElapsedMilliseconds() - StartTime ; 11451 (0.2 secs faster)
User avatar
STARGÅTE
Addict
Addict
Posts: 2259
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: "Smart" For?

Post by STARGÅTE »

Piero wrote: Sun Jan 26, 2025 1:58 am Yep, thanks! I just tested it:
That's not how to test properly.
Time measurements have to be performed always with disabled debugger.
Delay() is not time critical. Delay(1) not always waits exact 1 ms!

Here a test code that shows, how many times the loop condition is called:

Code: Select all

Procedure CallMy(Value.i)
	Debug "is called"
	ProcedureReturn Value
EndProcedure

Define I.i

For I = 1 To CallMy(5)
	Debug "loop content"
Next
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: "Smart" For?

Post by Piero »

STARGÅTE wrote: Sun Jan 26, 2025 9:16 amThat's not how to test properly.
TY again!
Anyway I tested each "version" repeatedly, and results varied only very slightly…
I also tested using other loops instead of Delay.
I hoped that in very simple cases (e.g., calling a proc is not a very simple one) "optimization" could happen…

Weirdly, enabling "thread safe" seems to improve it! :shock:
But I just quickly tested now (on Mac ARM) out of pure curiosity, with Debugger and Delay :oops:

Edit/Note:
Please forgive me @STARGÅTE ; I wrote "TY again" thinking you had answered before, so I need to apologize with @BarryG too :oops: :oops:
Last edited by Piero on Mon Jan 27, 2025 9:16 pm, edited 1 time in total.
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: "Smart" For?

Post by idle »

compile without debugger

Code: Select all

For i=1 To 50000
   s.s+"."
Next
n=Len(s)

StartTime.q = ElapsedMilliseconds()
For i=1 To Len(s)
   a = n * i 
Next
et = ElapsedMilliseconds() - StartTime ; 11650

StartTime = ElapsedMilliseconds()
For i=1 To n
   a = n * i 
Next
et1 = ElapsedMilliseconds() - StartTime ; 11451 (0.2 secs faster)

out.s = "t1 = " + Str(et) + " t2= " + Str(et1) 
MessageRequester("times",out) 

User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: "Smart" For?

Post by Piero »

Idle with your example I would have to use an enormous string and wait hours for "et1" to be > 0, or get an overflow before :lol:

Seems that your "For i=1 To n" loop gets enormously optimized, also by the hardware (ARM)

Anyway there was no difference now in "et" (1st loop) with thread safe on
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: "Smart" For?

Post by idle »

The loop with len(s) is walking the string each time and it won't get optimized out by the compiler, but when you time the loop with delay(1) that's what your going to get is the time for delay 1ms, not the time it takes to do the len(s) thats probably due to out of order execution.
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: "Smart" For?

Post by Piero »

Resuming:

ALWAYS USE A NUMBER OR VARIABLE IN LOOPS IF POSSIBLE :wink:
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: "Smart" For?

Post by idle »

Piero wrote: Mon Jan 27, 2025 11:14 am Resuming:

ALWAYS USE A NUMBER OR VARIABLE IN LOOPS IF POSSIBLE :wink:
Yes. I was just trying to explain why you didn't see a big time difference with the delay(1) in the loop.
Post Reply