Change in array.ubound SpeedTricks?

Questions Regarding SpeedTricks for “For” statements with an array.ubound.

When I first go into XOJO, one of the speed tricks was “have a property so the UBound isn’t checked everytime”.

Is this trick still valid?
Example

For i = 0 To ArUbnd//An Integer property for the Ubound for CardArray and is a computed property. If CardArray(i).darta(xcol) = strg Then Exit For Next

If put in a computed property in the For statement it is checked every time.
Is just an integer property checked still?

yes… because a “value lookup” is much faster than a calculation

Don’t ask, don’t guess. Measure.

If the calculation isn’t complex and the operation isn’t done lots of times it’s unlikely to matter much.

Thanks. No change to plans then. I needed a computed property because every so often the UBound was like -2222 instead -1

I always thought the compiler was smart enough to detect whether the For/Next loop contains any code that would alter the terminating value, and if not, it would calculate the value just once at the start of the loop, and then use the calculated value thereafter. I guess I’ll have to do some tests too. :slight_smile:

A computed property is just a function which calls xxx.Ubound
To get your speed, you should take the computation out of the loop too

dim UpperLim as integer = ArUbnd For i = 0 To UpperLim

I agree. That is what I used to do.
I’m also grateful for the speed tricks so many years ago.

I ran into a weird anomaly.
For some reason, the starting number for an empty array was not -1 but some very negative number like 200,000. It’s the number which is actually 2 squared (20 times maybe) with a negative sign. It was easier accounting for that weird anomaly in a computed property than adding code.

I’m just curious why it matters. You should never test for -1 directly. It’s either >= 0 or < 0. And in a for loop you don’t need to check, that’s already built in.

dim a() as integer
for I as integer = 0 to ubound(a)
   // some code that will never be executed
next

Since ubound(a) is less than 0, the for loop will exit immediately. Also, Ubound is an inexpensive call, so I just leave it in the loop for readability.

While the 32 Bit compiler was and is not optimizing, this would even be hard for a much more sophisticated compiler like LLVM (although I don’t say it’s impossible): The compiler would need knowledge that the ubound of the array did not change in between two passes through the loop. A thread could have done so. Ubound is basically a method, so the compiler will most likely expect the result to be variable, therefore it will query it again.
With a separate variable, you can be sure to benefit from the possible speed boost.

EDIT:

Basically true, but it depends. In a loop that cycles only a handful of times but does many things in each turn you’ll hardly notice any difference at all. In a loop with numerous repetitions this might look differently.

While I would have agreed with you had you asked me yesterday… today I’m not so sure… at least in regards to Ubound()

I just did a test… doing it both ways, and the results were identical… which suffice to say, suprised me.

Now, if the value were to change, or if it were another function… things could be totally different… it just might be that Ubound costs exactly the same as looking up a “variable”

FYI… my test was 100 million interations

Which I cannot confirm, at least on a MacBook in a debugbuild. :smiley:
I used this code in a button’s action event:

Sub Action() Handles Action Dim d As xojo.core.date = xojo.core.date.now For q As Integer = 0 To Testarray.Ubound Testvalue = q^2 Next Dim t1 As Xojo.Core.DateInterval = xojo.core.date.now - d d = xojo.core.date.now Dim i As Integer = Testarray.Ubound For q As Integer = 0 To Testarray.Ubound Testvalue = q^2 Next Dim t2 As Xojo.Core.DateInterval = xojo.core.date.now - d Dim s1 As Double = t1.NanoSeconds Dim s2 As Double = t2.NanoSeconds Break End Sub
Most of the times s2 was about 2/3 of s1.
EDIT: For a test array of integer(4000) and Testvalue being a Double property.
With higher array ubounds, the results equalize and sometimes (400000) s2 > s1.
So what I wrote is half true: A speed bonus can be possible, but not depending on the facts I mentioned :wink:

Ubound is highly optimized and is similar to a property. It should be faster than a normal function call.

[quote=403734:@Ulrich Bogun]Which I cannot confirm, at least on a MacBook in a debugbuild. :smiley:
I used this code in a button’s action event:

Sub Action() Handles Action Dim d As xojo.core.date = xojo.core.date.now For q As Integer = 0 To Testarray.Ubound Testvalue = q^2 Next Dim t1 As Xojo.Core.DateInterval = xojo.core.date.now - d d = xojo.core.date.now Dim i As Integer = Testarray.Ubound For q As Integer = 0 To Testarray.Ubound Testvalue = q^2 Next Dim t2 As Xojo.Core.DateInterval = xojo.core.date.now - d Dim s1 As Double = t1.NanoSeconds Dim s2 As Double = t2.NanoSeconds Break End Sub
Most of the times s2 was about 2/3 of s1.
EDIT: For a test array of integer(4000) and Testvalue being a Double property.
With higher array ubounds, the results equalize and sometimes (400000) s2 > s1.
So what I wrote is half true: A speed bonus can be possible, but not depending on the facts I mentioned ;)[/quote]

Your two loops are identical:

For q As Integer = 0 To Testarray.Ubound Testvalue = q^2 Next

Maybe you meant

For q As Integer = 0 To i Testvalue = q^2 Next

for the second loop?

Also, doesn’t your t2 include the time of both loops?