Saturday, March 9, 2013

How to convert a collection to array

How to convert a collection to array

In today's example, we will try to send the items from a ListBox's collection to a regular array with Visual Studio. NET (Visual Basic 2005, 2008, 2010, 2012).

The wrong technique would be the most intuitive: the loop. The loop is to go through all the elements one by one. This technique, although it is easy to understand but is very long and the program used in this blog will prove it.
The second technique is to copy the all the handles from the collection of items in the ListBox to the array. This is what we learn at school the first year.

How to convert a collection to array



How the program works? It is very simple. The Button1 generates a list of values. This may take time and it is quite intentional. We must realize how "to create" values ​​takes a large amount of time.

Then, be free to press Button2 to measure the time required for transferring the data in the collection to an array. You should see a delay in the display n Label2 under Button2.

Then, try the Button3. It uses the CopyTo function. That function simply copies the handles. The result will be almost instantaneous. Press Button3 repeatedly to convince youself that there is indeed a delay, but very little true.

I hope this blog will help you better plan and also produce optimized programs
With my laptop purchased in December 2011 (Intel CORE i7-2670QM), I made the test results with 10000 values to transfer. The processing time is 4 times larger than the good practical method. With 1 million items, it is almost 15 times the time required to transfer data.

Blue is the reference. Red indicates poor technique.






''' <summary>
''' ENGLISH : This sample shows you how good programming is key for performance.
''' FRANÇAIS : Cet exemple illustre à quel point les bonnes techniques de programmation sont importantes
''' DEUTSCH : Dieses Beispiel zeigt Ihnen, wie gut Programmiertaste zur Leistung
''' </summary>
''' <remarks></remarks>
Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.Text = My.Application.Info.AssemblyName.ToString
        Label1.Text = "press this button to first fill the ListBox1" & Environment.NewLine
        Label1.Text = Label1.Text & "this might take some time" & Environment.NewLine
        Label1.Text = Label1.Text & "This is done on purpose"

        Label2.Text = "Here will display time to process a loop"

        Label3.Text = "Here will display time to process a copy"

        Button2.Enabled = False
        Button3.Enabled = False
    End Sub
    ''' <summary>
    ''' This fonction only fill the ListBox
    ''' it also give a basic animation
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub FillListBox()
        Dim max_count As Integer = 1000000
        Dim ran As System.Random = New System.Random()

        Me.Invoke(New MethodInvoker(Sub() Me.Button2.Enabled = False))
        Me.Invoke(New MethodInvoker(Sub() Me.Button3.Enabled = False))

        For i = 0 To max_count
            Me.Invoke(New MethodInvoker(Sub() ListBox1.Items.Add(ran.Next(-32000, 32000))))
            Me.Invoke(New MethodInvoker(Sub() Me.Label4.Text = i.ToString & "/" & max_count))
        Next

        Me.Invoke(New MethodInvoker(Sub() Me.Button2.Enabled = True))
        Me.Invoke(New MethodInvoker(Sub() Me.Button3.Enabled = True))
    End Sub
    ''' <summary>
    ''' Start filling the ListBox in Background
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim mythread As New Threading.Thread(AddressOf FillListBox)
        mythread.IsBackground = True
        mythread.Start()

    End Sub
    ''' <summary>
    ''' Convert a collection to array (BAD IDEA!!)
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Dim index1 As Integer
        Dim MyArray() As String
        Dim otime As Date
        otime = Date.Now
        ReDim MyArray(ListBox1.Items.Count - 1)
        For index1 = 0 To ListBox1.Items.Count - 1 Step 1
            MyArray(index1) = ListBox1.Items(index1)
        Next index1
        Label2.Text = (Date.Now.Subtract(otime).ToString)
    End Sub

    ''' <summary>
    ''' The way you should to it!
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        Dim MyArray() As Object
        Dim otime As Date
        otime = Date.Now
        ReDim MyArray(ListBox1.Items.Count - 1)
        ListBox1.Items.CopyTo(MyArray, 0)
        Label3.Text = (Date.Now.Subtract(otime).ToString)
    End Sub
End Class






Download the example here: SamplePerformanceCollectionToArray.zip



2 comments:

  1. This is a good logger:
    http://www.kellermansoftware.com/p-14-net-logging-library.aspx

    ReplyDelete
  2. Good information about convert collection to array.

    Convert VB6 to VB.NET

    ReplyDelete