开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜