Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using Lbound and ubound in for loop

Status
Not open for further replies.

Jeet2004

MIS
Jun 29, 2005
96
US
Hi,
I dont know which is more efficient way to do
using Lbound and ubound in for loop or first determining the lbound and ubound ,then saving them in variables and then using it.
for eg if i have an array test with 4 elements
so using
for i = lbound(test) to Ubound(test)
is more efficient or
lower= lbound(test)
upper= Ubound(test)
and for i= lower to upper
is more efficient.
I guess it boils down to question that in for loop does it itereates for each run or once it has done lower limit and upper limit it uses that value
Thanks
 
I'm pretty sure it uses the value. I believe this is what makes for next loops a bit more efficient than do while loops when you know ahead of time the number of iterations that you're going to perform.

Bob
 
In my opinion, it probably doesn't matter.

IF the lbound and ubound are calculated every time, the time required to calculate it will be negligible compared to anything happening inside the loop.

To illustrate my point, take a look at the following code. There is no appreciable difference in execution speed on my computer.

Code:
Private Sub Command1_Click()
    
    Dim sngStart As Single
    Dim sngEnd As Single
    
    Dim arTest() As Long
    Dim i As Long
    
    Dim lLower As Long
    Dim lUpper As Long
    
    ReDim arTest(9999999)
    
    sngStart = Timer
    For i = LBound(arTest) To UBound(arTest)
        arTest(i) = i
    Next
    sngEnd = Timer
    
    Debug.Print "Using Bounds: " & sngEnd - sngStart
    
    sngStart = Timer
    lLower = LBound(arTest)
    lUpper = UBound(arTest)
    For i = lLower To lUpper
        arTest(i) = i
    Next
    sngEnd = Timer
    
    Debug.Print "Settign Bounds First: " & sngEnd - sngStart
    
End Sub

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
so you mean to say that performance wise both the ways would yeild the same result.
 
Using For...Next in arrays is a lot faster than For...Each. I'm not sure why this is caused, but probably also because you've got to use a variant as loop index for the "For...Each". And any serious programmer doesn't use a variant in his/her applications.
 
>Using For...Next in arrays is a lot faster than For...Each

In general the difference on modern hardware is miniscule and to all intents unobservable to users unless the arrays exceed about 10 to 100 million elements - except if the array contains strings (mainly because of the poor way VB handles all string operations rather than because of the use of variants)

>And any serious programmer doesn't use a variant in his/her applications


If you say so.

I'd certainly advise caution in their use, but there are a few things you'll find difficult in VB without variants
 
strongm,

You forgot one! No serious programmer would use the Timer function to time anything. [bigsmile]

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
I tried George's program, and then compiled it and tried that too. In general, the using bounds is slightly faster than the setting to variables first, which bears out the idea that they get calcualated first.

As for using for each with arrays, I never even knew you could do that. I tried it in George's program, and yes, it is a whole lot slower. It would seem that for each should be used to iterate through object collections, the use for which it's intended.

It would also seem that something horribly messy and interesting is going on behind the scenes, probably involving some type of object getting created on the heap and mimicking the array. Maybe you have to use a variant because you have to contain not only the offset and value of any given array element but also a pointer to where the object resides. In any case, I'm pretty sure that that the performance hit is because we're accessing the heap instead of the stack, though.

Perhaps strongm has more information...

Bob
 
>As for using for each with arrays, I never even knew you could do that

Coo, you haven't been paying attention, Bob; I've used this construct in a number of examples that I know you've read ...

>the use for which it's intended

No. It is intended for any object that has an enumerator (and arrays do - well, they do once you call For Each on them ...). You can get your own classes to respond to it as well ...
 
Bob,

It looks like I didn't explain myself well. In the code I provided, I was doing something VERY simple inside the loop. I simply set an array element equal to a long. Most loops will have something more interesting going on.

Just for fun, change one of the loops so there is NO code inside the for loop, then run it and check the time. You'll notice that the time is much less when you are doing nothing. So my point is that the loop 'structure' is insignificant compared to the actions taken inside the loop.

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
Well, I'm sure that's probably true, George.

As for you, strongm, I always pay attention, I'm just absent-minded. :p Seriously, I don't remember ever noticing that in one of your posts, and I've never used it before. Although I use it all the time in collections of my own classes (if this isn't what you mean by getting my own classes to respond to it, feel free to elaborate). Can you point me to an example of yours wherein using for each with an array is a better solution than iterating through the offsets as is more common?

>It is intended for any object that has an enumerator (and arrays do - well, they do once you call For Each on them ...)
I wasn't aware that an array was automatically an object in VB! In fact, I thought it was some sort of internal implementation that resided on the main thread's stack.

My theory was that the slowdown occurred because for each iterated through collections, and an array isn't a collection, therefore a collection has to be created and populated with the array values and then for each would iterate that, after which everything is broken down again. Now you're suggesting that an array already is an object, which halfway messes up my theory.

So, I did a little digging around, and learned a little bit about Safearray structures/types. VB6 arrays are all Safearrays. Now, structures are allocated on the stack. Collections, on the other hand, are objects, and therefore allocated on the heap. So, perhaps my theory is correct, after all.

What you say about enumerators is interesting, and tends to bear out the theory as well. I looked up the definition of enumerator, and it's an object that provides an interface to allow iteration through a linked array object.

So, it would seem that what's going on is the equivalent of boxing in the .Net world, with the additional overhead of creating an enumerator object, and then unboxing again. So, the added overhead has to do with
1. Creating an object wrapper for the safearray type.
2. Creating an enumerator object.
3. Accessing an object iteratively instead of a type.

Any corrections?

Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top