I did some timings, and didn't see the percentages you saw.
I tried the .length method directly in the for/until statement, copying it to a local var and using the local var in the for statement and also using the For/EachIn.
Try this and see how you go (will only work on Win32, as I used the RDTSC, via QueryPerformanceCounter).
A useful piece of code in there is the TCodeTimer class, which gives you an accurate nano-second timer (dependant on CPU speed). I saw some of you asking for a better than millisecond timer, so I thought I'd provide this.
Framework brl.retro
' initialize the timer internals
TCodeTimer.Initialise()
Print "Timing 1..."
Local myarray:Int[1000]
Local dummy:Int
timer:TCodeTimer = TCodeTimer.Create()
timer.StartWatch()
While timer.WatchTime() < 1000
timer.StartTimer()
Local ma_len:Int = myarray.length - 1
For counter = 0 To ma_len
dummy = myarray[counter]
Next
timer.StopTimer()
Wend
Print "Using length in local variable"
Print "Iterations: " + timer._iterations
Print "Total Time: " + timer._totaltime
Print "Average time: " + timer._totaltime / Double(timer._iterations)
Print "***************************"
Print
timer.ResetTimer()
Print "Timing 2..."
timer.StartWatch()
While timer.WatchTime() < 1000
timer.StartTimer()
For counter = 0 Until myarray.length
dummy = myarray[counter]
Next
timer.StopTimer()
Wend
Print "Using length in For/Until"
Print "Iterations: " + timer._iterations
Print "Total Time: " + timer._totaltime
Print "Average time: " + timer._totaltime / Double(timer._iterations)
Print "***************************"
Print
timer.ResetTimer()
Print "Timing 3..."
timer.StartWatch()
While timer.WatchTime() < 1000
timer.StartTimer()
For value=EachIn myarray
Next
timer.StopTimer()
Wend
Print "Using length in For/Until"
Print "Iterations: " + timer._iterations
Print "Total Time: " + timer._totaltime
Print "Average time: " + timer._totaltime / Double(timer._iterations)
Print "***************************"
Print
' classes
Extern "win32"
Function QueryPerformanceCounter(count:Long Var)
Function QueryPerformanceFrequency(freq:Long Var)
End Extern
Type TCodeTimer
Field _start:Long
Field _stop:Long
Field _iterations:Int
Field _totaltime:Double
Method ResetTimer()
_start = 0
_stop = 0
_iterations = 0
_totaltime = 0
End Method
Method StartTimer()
QueryPerformanceCounter(_start)
End Method
Method StopTimer()
QueryPerformanceCounter(_stop)
_totaltime :+ (Double(_stop - _start) / Double(_freq))
_iterations :+ 1
End Method
''' Stopwatch functions
Field _watchstart:Double
Method StartWatch()
self._watchstart = QueryCounter()
End Method
''' returns the number of milliseconds since calling StartWatch()
Method WatchTime:Double()
Return QueryCounter() - _watchstart
End Method
''' Globals
''' Initialize should be called before first use, to determine timer class overhead
Global _overhead:Double
Global _freq:Long
Function Create:TCodeTimer()
Return New TCodeTimer
End Function
Function Initialise()
QueryPerformanceFrequency(_freq)
_freq :/ 1000
End Function
Function QueryCounter:Double()
Local counter:Long
QueryPerformanceCounter(counter)
Return Double(counter) / _freq
End Function
End Type