Vishwamohan

Welcome to Vishwa's blog - Technology, Spirituality and More...

Speed Test: Generic List vs. ArrayList

It is very important to evaluate the most efficient way of passing data between layers. Many people recommend using ArrayList, some Generic List. But which one is the most efficient way to use? I thought to perform a speed test between Generic List and ArrayList in VS2005. Some people blindly accept that ArrayList is the fastest way. But is it true? Let’s have a real test by reading and writing hundred thousand records using each type and see the outcome. Knowing the fact that Collection, Data Table and XML is slower than these two but how much? Let’s put them to test too and compare the result.

 Following Windows From returns the result 

 

 From the above data, Generic List is a clear winner. The only downside is you have to write extra code for that. However, ArrayList takes the second place and relatively good with respect to Collection, Data Table or XML. So the decision is based on how efficient you want? You have to also realize the fact that in ArrayList, you will have 2 issues .First, you have to always retrieve data based on index (does not clearly tells you which column you are reading unless you know the mapping ). Second, you pay the penalty of Boxing/Unboxing, because every element in the ArrayList is an object, you will have to convert them to their actual data type. The benefit is you have to write less code and still achieve the better performance. 

 Following link gives more information and clear understanding on non generic and generic type and where to use what

http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx

Another important thing you must consider under 64 bit Operating System. Following is an article you can read.

http://blogs.msdn.com/joshwil/archive/2004/04/13/112598.aspx

Some of you asked as where is the code. I am dropping the code here, you can checkout on your own

Public Class FormSpeedTest
 
    Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
 
        btnRun.Enabled = False
 
        Call WriteArrayListData()
 
        Call WriteCustomerObjectData()
 
        Call WriteDataTableData()
 
        btnRun.Enabled = True
 
    End Sub
 
    Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click
 
        btnRead.Enabled = False
 
        Call ReadArrayListData()
 
        Call ReadCustomerObjectData()
 
        Call ReadFromCustomerTable()
 
        Call ReadFromCustomerTableOptimization1()
 
        Call ReadFromCustomerTableOptimization2()
 
        'Call ReadXMLFromCustomerTable()
 
        btnRead.Enabled = True
 
    End Sub
 
    '/***********************ARRAY LIST Functionality ****************************************/
 
    Private Function WriteToArrayListByValue(ByVal custID As Int32, ByVal custName As String, ByVal custSex As Boolean, _
 
            ByVal custSalary As Decimal, ByVal custMaritalStatus As Char, ByVal custDOB As DateTime) As Object
 
        Dim arrCustomer As New ArrayList()
 
        arrCustomer.Add(custID)
 
        arrCustomer.Add(custName)
 
        arrCustomer.Add(custSex)
 
        arrCustomer.Add(custSalary)
 
        arrCustomer.Add(custMaritalStatus)
 
        arrCustomer.Add(custDOB)
 
        Return arrCustomer
 
    End Function
 
    Private Function WriteToArrayListFromArrayList(ByVal arrCust As ArrayList) As Object
 
        Dim arrCustomer As New ArrayList()
 
        arrCustomer.Add(arrCust(0))
 
        arrCustomer.Add(arrCust(1))
 
        arrCustomer.Add(arrCust(2))
 
        arrCustomer.Add(arrCust(3))
 
        arrCustomer.Add(arrCust(4))
 
        arrCustomer.Add(arrCust(5))
 
        Return arrCustomer
 
    End Function
 
    Private Sub WriteArrayListData()
 
        Dim stpWatch1 As New Diagnostics.Stopwatch
 
        Dim customerList As New ArrayList
 
        Dim customerObj As New List(Of SpeedTestCustomer)
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
        stpWatch1.Start()
 
        For i As Integer = 0 To 1000000
 
            customerList.Add(WriteToArrayListByValue(i, "Customer Name " & i.ToString, s, l * i, m, d))
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
        stpWatch1.Stop()
 
        lblArrayListWriteMsg.Text = "Loading an ArrayList Object with " & customerList.Count.ToString & " Items. Total Duration : " & (stpWatch1.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
 
 
    End Sub
 
    Private Sub ReadArrayListData()
 
        Dim stpWatch1 As New Diagnostics.Stopwatch
 
        Dim customerList As New ArrayList
 
        Dim custX As New ArrayList
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
        '/*************LOAD FIRST ********************************/
 
        For i As Integer = 0 To 1000000
 
            customerList.Add(WriteToArrayListByValue(i, "Customer Name " & i.ToString, s, 1 * i, m, d))
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
        stpWatch1.Start()
 
        For i As Integer = 0 To customerList.Count - 1
 
            custX.Add(WriteToArrayListFromArrayList(CType(customerList(i), ArrayList)))
 
        Next
 
        stpWatch1.Start()
 
        lblArrayListReadMsg.Text = "Reading an ArrayList Object with " & customerList.Count.ToString & " Items. Total Duration : " & (stpWatch1.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
 
 
    End Sub
 
    '/***********************Data Table Functionality ****************************************/
 
 
 
    Private Function CreateCustomerTable() As DataTable
 
        Dim dt As New DataTable("Customer")
 
        Dim dc1 As New DataColumn("CustId", GetType(Integer))
 
        Dim dc2 As New DataColumn("Name", GetType(String))
 
        Dim dc3 As New DataColumn("Sex", GetType(Boolean))
 
        Dim dc4 As New DataColumn("Salary", GetType(Decimal))
 
        Dim dc5 As New DataColumn("MaritalStatus", GetType(Char))
 
        Dim dc6 As New DataColumn("BirthDate", GetType(DateTime))
 
 
 
        dt.Columns.Add(dc1)
 
        dt.Columns.Add(dc2)
 
        dt.Columns.Add(dc3)
 
        dt.Columns.Add(dc4)
 
        dt.Columns.Add(dc5)
 
        dt.Columns.Add(dc6)
 
 
 
        Return dt
 
    End Function
 
    Private Sub WriteDataTableData()
 
        Dim stpWatch3 As New Diagnostics.Stopwatch
 
        Dim custTable As New DataTable
 
        custTable = CreateCustomerTable()
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
        stpWatch3.Start()
 
        For i As Integer = 0 To 1000000
 
            Dim dr As DataRow = custTable.NewRow
 
 
 
            dr("CustID") = i
 
            dr("Name") = "Customer Name " & i.ToString
 
            dr("Sex") = s
 
            dr("Salary") = l * i
 
            dr("MaritalStatus") = m
 
            dr("BirthDate") = d
 
            custTable.Rows.Add(dr)
 
 
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
        stpWatch3.Stop()
 
        lblTableWriteMsg.Text = "Loading a Data Table Object with " & custTable.Rows.Count.ToString & " Items. Total Duration :" & (stpWatch3.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
    End Sub
 
    Private Sub ReadFromCustomerTable()
 
        Dim stpWatch4 As New Diagnostics.Stopwatch
 
 
 
        Dim custTable As New DataTable
 
        custTable = CreateCustomerTable()
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
 
 
        For i As Integer = 0 To 1000000
 
            Dim dr As DataRow = custTable.NewRow
 
 
 
            dr("CustID") = i
 
            dr("Name") = "Customer Name " & i.ToString
 
            dr("Sex") = s
 
            dr("Salary") = l * i
 
            dr("MaritalStatus") = m
 
            dr("BirthDate") = d
 
            custTable.Rows.Add(dr)
 
 
 
            If s Then s = False Else s = True
 
            If m = CChar("S") Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
 
 
        Dim custTableNew As New DataTable
 
        custTableNew = CreateCustomerTable()
 
        stpWatch4.Start()
 
        For i As Integer = 0 To custTable.Rows.Count - 1
 
            Dim dr As DataRow = custTableNew.NewRow
 
            dr("CustID") = CInt(custTable.Rows(i).Item(0))
 
            dr("Name") = custTable.Rows(i).Item(1).ToString
 
            dr("Sex") = CBool(custTable.Rows(i).Item(2))
 
            dr("Salary") = CDec(custTable.Rows(i).Item(3))
 
            dr("MaritalStatus") = CChar(custTable.Rows(i).Item(4))
 
            dr("BirthDate") = CDate(custTable.Rows(i).Item(5))
 
            custTableNew.Rows.Add(dr)
 
        Next
 
        stpWatch4.Stop()
 
        lblTableReadMsg.Text = "Reading a Data Table Object with " & custTableNew.Rows.Count.ToString & " Items. Total Duration :" & (stpWatch4.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
    End Sub
 
    Private Sub ReadFromCustomerTableOptimization2()
 
        Dim stpWatch6 As New Diagnostics.Stopwatch
 
 
 
        Dim custTable As New DataTable
 
        custTable = CreateCustomerTable()
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
 
 
        For i As Integer = 0 To 1000000
 
            Dim dr As DataRow = custTable.NewRow
 
 
 
            dr("CustID") = i
 
            dr("Name") = "Customer Name " & i.ToString
 
            dr("Sex") = s
 
            dr("Salary") = l * i
 
            dr("MaritalStatus") = m
 
            dr("BirthDate") = d
 
            custTable.Rows.Add(dr)
 
 
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
 
 
        Dim custTableNew As New DataTable
 
        custTableNew = CreateCustomerTable()
 
        stpWatch6.Start()
 
 
 
        If custTable.Rows.Count > 0 Then
 
            Dim custIDColumn As DataColumn = custTable.Columns("CustID")
 
            Dim custNameColumn As DataColumn = custTable.Columns("Name")
 
            Dim custSexColumn As DataColumn = custTable.Columns("Sex")
 
            Dim custSalaryColumn As DataColumn = custTable.Columns("Salary")
 
            Dim custMaritalStatusColumn As DataColumn = custTable.Columns("MaritalStatus")
 
            Dim custBirthDateColumn As DataColumn = custTable.Columns("BirthDate")
 
 
 
            For Each rowOrder As DataRow In custTable.Rows
 
                Dim dr As DataRow = custTableNew.NewRow
 
                dr("CustID") = CInt(rowOrder.Item(custIDColumn))
 
                dr("Name") = rowOrder.Item(custNameColumn).ToString
 
                dr("Sex") = CBool(rowOrder.Item(custSexColumn))
 
                dr("Salary") = CDec(rowOrder.Item(custSalaryColumn))
 
                dr("MaritalStatus") = CChar(rowOrder.Item(custMaritalStatusColumn))
 
                dr("BirthDate") = CDate(rowOrder.Item(custBirthDateColumn))
 
                custTableNew.Rows.Add(dr)
 
            Next
 
        End If
 
        stpWatch6.Stop()
 
        lblTableOpt2ReadMsg.Text = "Reading a Data Table Object 2nd Optimization with " & custTableNew.Rows.Count.ToString & " Items. Total Duration :" & (stpWatch6.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
    End Sub
 
    Private Sub ReadFromCustomerTableOptimization1()
 
        Dim stpWatch5 As New Diagnostics.Stopwatch
 
 
 
        Dim custTable As New DataTable
 
        custTable = CreateCustomerTable()
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
 
 
        For i As Integer = 0 To 1000000
 
            Dim dr As DataRow = custTable.NewRow
 
 
 
            dr("CustID") = i
 
            dr("Name") = "Customer Name " & i.ToString
 
            dr("Sex") = s
 
            dr("Salary") = l * i
 
            dr("MaritalStatus") = m
 
            dr("BirthDate") = d
 
            custTable.Rows.Add(dr)
 
 
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
 
 
        Dim custTableNew As New DataTable
 
        custTableNew = CreateCustomerTable()
 
        stpWatch5.Start()
 
 
 
        Using reader As DataTableReader = custTable.CreateDataReader
 
            Dim custIDOrdNo As Integer = reader.GetOrdinal("CustID")
 
            Dim custNameOrdNo As Integer = reader.GetOrdinal("Name")
 
            Dim custSex As Integer = reader.GetOrdinal("Sex")
 
            Dim custSalaryOrdNo As Integer = reader.GetOrdinal("Salary")
 
            Dim custMaritalStatusOrdNo As Integer = reader.GetOrdinal("MaritalStatus")
 
            Dim custBirthDateOrdNo As Integer = reader.GetOrdinal("BirthDate")
 
 
 
            Do While reader.Read
 
                Dim dr As DataRow = custTableNew.NewRow
 
                dr("CustID") = reader.GetInt32(custIDOrdNo)
 
                dr("Name") = reader.GetString(custNameOrdNo)
 
                dr("Sex") = reader.GetBoolean(custSex)
 
                dr("Salary") = reader.GetDecimal(custSalaryOrdNo)
 
                dr("MaritalStatus") = reader.GetChar(custMaritalStatusOrdNo)
 
                dr("BirthDate") = reader.GetDateTime(custBirthDateOrdNo)
 
                custTableNew.Rows.Add(dr)
 
            Loop
 
        End Using
 
 
 
        stpWatch5.Stop()
 
        lblTableOpt1ReadMsg.Text = "Reading a Data Table Object 1st Optimization with " & custTableNew.Rows.Count.ToString & " Items. Total Duration :" & (stpWatch5.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
    End Sub
 
    '/***********Customer Object Data Funcationality ******************/
 
 
 
    Private Sub WriteCustomerObjectData()
 
        Dim stpWatch2 As New Diagnostics.Stopwatch
 
        Dim customerList As New ArrayList
 
        Dim customerObj As New List(Of SpeedTestCustomer)
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = 1
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
        stpWatch2.Start()
 
        For i As Integer = 0 To 1000000
 
            Dim x As New SpeedTestCustomer(i, "Customer Name " & i.ToString, s, 1 * i, m, d)
 
            customerObj.Add(x)
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
        stpWatch2.Stop()
 
        lblCustomerWriteMsg.Text = "Loading a Custom Business Object with " & customerObj.Count.ToString & " Items. Total Duration :" & (stpWatch2.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
 
 
    End Sub
 
 
 
    Private Sub ReadCustomerObjectData()
 
        Dim stpWatch2 As New Diagnostics.Stopwatch
 
        Dim customerObj As New List(Of SpeedTestCustomer)
 
        Dim custY As New List(Of SpeedTestCustomer)
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = 1
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
        '/*************LOAD FIRST ********************************/
 
        For i As Integer = 0 To 1000000
 
            Dim x As New SpeedTestCustomer(i, "Customer Name " & i.ToString, s, 1 * i, m, d)
 
            customerObj.Add(x)
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
        '/**********************************READ NOW **********************/
 
        stpWatch2.Start()
 
        For i As Integer = 0 To customerObj.Count - 1
 
            custY.Add(customerObj(i))
 
        Next
 
        stpWatch2.Stop()
 
        lblCustomerReadMsg.Text = "Reading a Custom Business Object with " & customerObj.Count.ToString & " Items. Total Duration :" & (stpWatch2.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
 
 
    End Sub
 
    Private Sub ReadXMLFromCustomerTable()
 
        Dim stpWatch9 As New Diagnostics.Stopwatch
 
        Dim custTable As New DataTable
 
        Dim custArrayList As New ArrayList
 
        custTable = CreateCustomerTable()
 
 
 
        Dim s As Boolean = False
 
        Dim l As Decimal = CDec(1.278)
 
        Dim m As Char = CChar("S")
 
        Dim d As DateTime = #1/1/1901#
 
 
 
 
 
        For i As Integer = 0 To 100000
 
            Dim dr As DataRow = custTable.NewRow
 
 
 
            dr("CustID") = i
 
            dr("Name") = "Customer Name " & i.ToString
 
            dr("Sex") = s
 
            dr("Salary") = l * i
 
            dr("MaritalStatus") = m
 
            dr("BirthDate") = d
 
            custTable.Rows.Add(dr)
 
 
 
            If s Then s = False Else s = True
 
            If m = "S" Then m = CChar("M") Else m = CChar("S")
 
            d = DateAdd(DateInterval.Day, 1, d)
 
        Next
 
 
 
        Dim strXML As String = ConvertDataTableToXML(custTable)
 
        stpWatch9.Start()
 
        Dim xmlDoc As Xml.XmlDocument = New Xml.XmlDocument()
 
        xmlDoc.LoadXml(strXML)
 
 
 
        For Each xmlNode As Xml.XmlNode In xmlDoc.SelectSingleNode("/Customer")
 
            Dim localArrayList As New ArrayList()
 
            localArrayList.Add(xmlNode.Item("CustId").InnerText)
 
            localArrayList.Add(xmlNode.Item("Name").InnerText)
 
            localArrayList.Add(xmlNode.Item("Sex").InnerText)
 
            localArrayList.Add(xmlNode.Item("Salary").InnerText)
 
            localArrayList.Add(xmlNode.Item("MaritalStatus").InnerText)
 
            localArrayList.Add(xmlNode.Item("BirthDate").InnerText)
 
            custArrayList.Add(localArrayList)
 
        Next
 
 
 
        stpWatch9.Stop()
 
       lblXMLReadMsg.Text = "Reading a XML Object into an ArrayList with " & custArrayList.Count.ToString & " Items. Total Duration :" & (stpWatch9.ElapsedMilliseconds / 1000).ToString & " Seconds."
 
    End Sub
 
 
 
    Private Function ConvertDataTableToXML(ByVal dTable As DataTable) As String
 
        Dim dt As DataTable = dTable
 
        Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder
 
        sb.Append(("<" _
 
                        + (dt.TableName + ">")))
 
        For Each row As DataRow In dt.Rows
 
            sb.Append("<Item>")
 
            Dim i As Integer = 0
 
            Do While (i < dt.Columns.Count)
 
                sb.Append(("<" _
 
                                + (dt.Columns(i).ColumnName + (">" _
 
                                + (row(i).ToString + ("</" _
 
                                + (dt.Columns(i).ColumnName + ">")))))))
 
                i = (i + 1)
 
            Loop
 
            sb.Append("</Item>")
 
        Next
 
        sb.Append(("</" _
 
                        + (dt.TableName + ">")))
 
        Return sb.ToString
 
    End Function
 
 
 
 
 
End Class
 
Public Class SpeedTestCustomer
 
 
 
    Private _custID As Int32
 
    Private _custName As String
 
    Private _custSex As Boolean
 
    Private _custSalary As Decimal
 
    Private _custMaritalStatus As Char
 
    Private _custDOB As DateTime
 
 
 
    Public Property CustID() As Int32
 
        Get
 
            Return _custID
 
        End Get
 
        Set(ByVal value As Int32)
 
            _custID = value
 
        End Set
 
    End Property
 
 
 
    Public Property Name() As String
 
        Get
 
            Return _custName
 
        End Get
 
        Set(ByVal value As String)
 
            _custName = value
 
        End Set
 
    End Property
 
 
 
    Public Property Sex() As Boolean
 
        Get
 
            Return _custSex
 
        End Get
 
        Set(ByVal value As Boolean)
 
            _custSex = value
 
        End Set
 
    End Property
 
 
 
    Public Property Salary() As Decimal
 
        Get
 
            Return _custSalary
 
        End Get
 
        Set(ByVal value As Decimal)
 
            _custSalary = value
 
        End Set
 
    End Property
 
 
 
    Public Property MaritalStatus() As Char
 
        Get
 
            Return _custMaritalStatus
 
        End Get
 
        Set(ByVal value As Char)
 
            _custMaritalStatus = value
 
        End Set
 
    End Property
 
 
 
    Public Property DateOfBirth() As DateTime
 
        Get
 
            Return _custDOB
 
        End Get
 
        Set(ByVal value As DateTime)
 
            _custDOB = value
 
        End Set
 
    End Property
 
 
 
#Region " Constructors"
 
    Public Sub New(ByVal custID As Int32, ByVal custName As String, ByVal custSex As Boolean, _
 
        ByVal custSalary As Decimal, ByVal custMaritalStatus As Char, ByVal custDOB As DateTime)
 
        Me.CustID = custID
 
        Me.Name = custName
 
        Me.Sex = custSex
 
        Me.Salary = custSalary
 
        Me.MaritalStatus = custMaritalStatus
 
        Me.DateOfBirth = custDOB
 
    End Sub
 
#End Region
 
End Class
 
 
 
 

Comments (3) -

  • al

    3/17/2008 2:06:09 PM | Reply

    From Where can I download your "Speed Test" project?

  • dg

    4/28/2008 12:40:58 PM | Reply

    Where can I download your "Speed  Test" project?
    I did the same I tested arraylist vs Generecis and I get better performance using arraylist.

  • dhana

    11/13/2008 12:58:55 AM | Reply

    pls post the solution for download. that wil be helpful for all.

Loading