Yeah, I've thought about that
But I'm sure LEN(ARRAY) only fetches a quick value, no real computations are done, so the changes would be negligible
But, when a for loop has a huge number of iterations to do, function calls can be a lot more computationally expensive (from experience) so this would be a smart trick to consider.
faster FOR loop
Root / Submissions / [.]
12Me21Created:
Often people use something like FOR I=0 TO LEN(ARRAY)-1 to loop through an array, but this isn't optimal since it checks the length on each pass through the loop.
A simple fix is to do: VAR L=LEN(ARRAY)-1:FOR I=0 TO L, but there is a better way: FOR I=LEN(ARRAY)-1 TO 0 STEP -1.
This will only check the length once, and it doesn't have to set an extra variable. It will loop backwards, but that's fine if you're making an uppercase conversion function or something.
Replying to:haloopdy
I thought step -1 was actually really slow.
Like... it actually runs twice as slow as a regular empty for loop or something. Or was that PTC?
I think it's about the same speed as normal.
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
One other thing to mention:
having a step of two is faster than a step of one:
DEF whatever N 'stuff END FOR I = LEN(ARRAY) - 2 TO 0 STEP -2 CALL "whatever",ARRAY[I] CALL "whatever",ARRAY[I+1] NEXT
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
>you shouldn't define L and just do this because defining takes time
you always post the dumbest non-help
The page suggests not defining L because there's a workaround, but um, yes, pre-calculating an end value (if appropriate) is going to be faster than leaving an expression that has to be evaluated every iteration.
Variable definition and lookup is almost never going to be slower than evaluating a variable expression. The only exception I can think of is an actual table for functions that are built in, e.g. sine lookup table is slower than just calling SIN()
evaluating two cells at once STILL doesn't make sense usually. If you're worried about FOR overhead, why not just unroll the loop entirely? In any case, stepping by 2 only works if it is given that ARRAY will be even.
If you do know some special properties about the array then yes, it is possible to operate on more than one cell per iteration... but I would never think of this in terms of performance.
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
you're right
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
actually... I may have to take back what I said about partial unrolling.
I tested using this code:
DIM A[0], K%, M% M% = MILLISEC FOR I% = 0 TO 1000000 PUSH A, RND(512) NEXT ?"array generation took ";MILLISEC-M% ?"Step 1" M% = MILLISEC FOR I% = 999999 TO 0 STEP -1 K% = A[I%] NEXT ?MILLISEC - M% ?"Step 2" M% = MILLISEC FOR I% = 999999 TO 0 STEP -2 K% = A[I%] K% = A[I% - 1] NEXT ?MILLISEC - M%
array generation took 3954 Step 1 2163 Step 2 1699Results were consistent on cold run and 100000 elements But maybe I messed something up, so someone should check me. Still, the overhead only matters on huge arrays. The difference scaled down to 40ms at 100000 elements.
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
That is a VERY important thing I learned a while back
Replying to:DFrost
actually, you shouldn't define L and just do this:
FOR I = LEN(ARRAY)-1 TO 0 STEP -1 because defining takes time
it looks OK to me. K% is set once for every step(twice for 2 steps,once for 1 step) so it is an even 'fight'
Also, I hope this is perfect code because this could help Simeon with SIM.3D