Why one over another: UBound or Length
Could there be any specific reason why one can choose UBound
over Length
?
Here is the code and 1-dimension is开发者_Python百科 passed as second parameter.
For iIndex = 0 To UBound(myList)
If Left(Request.ServerVariables("REMOTE_ADDR"), Len(myList(iIndex))) = saIPList(iIndex) Then
bAuth = True
Exit For
End If
Next
Any performance gain against Length
They do different things! UBound
gives you the last index in the array, while Length
gives you the length. Those are not the same, because usually UBound
will be Length - 1
.
Ubound exists mainly for backwards compatibility to old code. I haven't seen anything saying it's deprecated just yet, but at the same time I recognize it's not really aligned with the way they have been taking the language in recent years. The same is true for the Len() and Left() functions in that code; they are the way of the past, not the future. The sooner you adapt, the happier you will be.
For what it's worth, the argument is largely moot. More "modern" ways to write that code look entirely different. Here's one example:
bAuth = myList.Zip(saIPList, Function(a,b) New With {.Length = a.Length, .saIP = b} ) _
.Any(Function(i) Request.ServerVariables("REMOTE_ADDR").ToString().SubString(0,i.Length) = i.saIP)
For performance gain I was also interested in what function has the best performance.
It seems that the length -1 is much faster than the UBound. I expected UBound to be faster somehow.
After 100.000.000 times it seems the time for length -1 is 952ms and for UBound: 5844ms.
(length -1) is ~6 times faster than UBound
Code used for testing
Private Sub UboundlengthToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UboundlengthToolStripMenuItem.Click
ListBox1.Items.Clear()
ListBox1.Items.Add("BEGIN")
'set required vars
Dim ints() As Integer = {1, 2, 3, 4, 5}
'end vars setting
Dim t As New Stopwatch
Dim gt As New Stopwatch
Dim time1 As Integer
Dim temp As Integer
Dim d As Double = GC.GetTotalMemory(False)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.GetTotalMemory(False)
ListBox1.Items.Add("Free Memory: " & d)
gt.Start()
t.Reset()
'starting test---------------------------------------
'single test---------------------------------------
t.Start()
For i As Integer = 0 To TextBox1.Text
temp = ints(ints.Length - 1)
Next
t.Stop()
time1 = t.ElapsedMilliseconds
ListBox1.Items.Add("arr.length - 1")
ListBox1.Items.Add("Func1 total time: " & time1)
ListBox1.Items.Add("Func1 single time: " & time1 / TextBox1.Text)
t.Reset()
'single test---------------------------------------
'single test---------------------------------------
t.Start()
For i As Integer = 0 To TextBox1.Text
temp = ints(UBound(ints))
Next
t.Stop()
time1 = t.ElapsedMilliseconds
ListBox1.Items.Add("UBound:")
ListBox1.Items.Add("Func1 total time: " & time1)
ListBox1.Items.Add("Func1 single time: " & time1 / TextBox1.Text)
t.Reset()
'single test---------------------------------------
'Finishing test--------------------------------------
gt.Stop()
ListBox1.Items.Add("Total time " & gt.ElapsedMilliseconds)
d = GC.GetTotalMemory(True) - d
ListBox1.Items.Add("Total Memory Heap consuming (bytes)" & d)
ListBox1.Items.Add("END")
End Sub
Tried different things to eliminate possible optimalisations of the compiler, all with the same result as stated above.
It's carried over from earlier VB days. UBound can give you the highest index of any single dimension in a multi-dimensional array. Length only gives you the total number of elements.
If you declare:
' A 5x10 array:
Dim array(4, 9) As Integer
The values are:
array.Length = 50 ' Total number of elements.
array.Rank = 2 ' Total number of dimensions.
array.LBound(0) = 0 ' Minimum index of first dimension.
array.LBound(1) = 0 ' Minimum index of second dimension.
array.UBound(0) = 4 ' Maximum index of first dimension.
array.UBound(1) = 9 ' Maximum index of second dimension.
Interesting UBounds is quite a bit faster in this example
Dim startTick As Long
For j As Integer = 1 To 5
Dim rnd As New Random(Now.Subtract(Now.Date).TotalSeconds)
Dim RandomMax As Integer = rnd.Next(10000, 100000)
Dim cumbersome() As Integer = New Integer() {rnd.Next}
'Ubound is better than Length. Using Length takes as much time as redimensioning the entire array.
startTick = Environment.TickCount
For i As Integer = 1 To RandomMax - 1
ReDim Preserve cumbersome(UBound(cumbersome) + 1)
cumbersome(UBound(cumbersome)) = Rnd.Next
Next
Debug.Print("{0}) Array Method UBound: {1} Ticks to construct {2} integers", j, Environment.TickCount - startTick, RandomMax)
'Length is slow don't use it
startTick = Environment.TickCount
For i As Integer = 1 To RandomMax - 1
ReDim Preserve cumbersome(cumbersome.Length)
cumbersome(cumbersome.Length - 1) = Rnd.Next
Next
Debug.Print("{0}) Array Method Length: {1} Ticks to construct {2} integers", j, Environment.TickCount - startTick, RandomMax)
Next
精彩评论