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

 

 

Signature

Comments

3/17/2008 7:06:09 PM #

al

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

al Israel

4/28/2008 5:40:58 PM #

dg

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

dg United States

11/13/2008 5:58:55 AM #

dhana

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

dhana India

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading



About Me

Me Hello,my name is Vishwa Mohan Kumar.
I am a Software Architect. This blog is result of my experiments.

Flickr Photos

Calendar

<<  February 2010  >>
MoTuWeThFrSaSu
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567

View posts in large calendar

Recent Comments

Comment RSS

Live Traffic Feed