Speedy generics

Posted on February 20, 2009 by Steve

In the Microsoft Press Training Kit for MCTS Exam 70-536, Tony Northrup writes:
I haven't been able to reproduce the performance benefits of generics; however, according to Microsoft, generics are faster than using casting. In practice, casting proved to be several times faster than using a generic. However, you probably won’t notice performance differences in your applications. (My tests over 100,000 iterations took only a few seconds.) So you should still use generics because they are type-safe.
I recently found that using generics offered a significant improvement to a complicated patch of code I'm working on. Here's a simple demonstration.
Dim ht As New Hashtable
Dim sw As New System.Diagnostics.Stopwatch
sw.Start()
For i As Integer = 1 To 10000
    For j As Integer = 1 To 10000
        If ht.Contains(i) Then
            ht(i) = j
        Else
            ht.Add(i, j)
        End If
    Next
Next
sw.Stop()
Console.Write("Hashtable time(ms): " & sw.ElapsedMilliseconds)
Average time over six runs was 11157 ms for a debug build and 11305 for a release build, compared to:
Dim sw As New System.Diagnostics.Stopwatch
Dim dic As New Dictionary(Of Integer, Integer)
sw.Start()
For i As Integer = 1 To 10000
    For j As Integer = 1 To 10000
        If dic.ContainsKey(i) Then
            dic(i) = j
        Else
            dic.Add(i, j)
        End If
    Next
Next
sw.Stop()
Console.Write("Generic dictionary time(ms): " & sw.ElapsedMilliseconds)
which took 4431 ms in debug and 3610 in release, improvements of 60% and 68% respectively.

I was clued in to the cost of boxing and unboxing by dotTrace, a handy profiler with a ten day trial. It burrowed into my thousand-line mass of code and showed that 85% of the method's runtime was consumed by CompilerServices.NewLateBinding.LateIndexGet and LateGet calls. The next most expensive method was SortedList.get_Item, using only 1% of the overall time, despite being called a third as often as the other two methods combined.

So I dumped my HashTables and ArrayList objects in favor of generic Dictionary(of String, String) and List(of String) objects. With these generics, the late binding was eliminated and the sprightly get_Item now represented 8% of the runtime, while overall performance was nicely improved.

But why are these collections, which require you to specify the datatypes that they contain, called "generics"? It makes sense, in a way. You do have to specify their contents, but generic collections can contain any type, whereas non-generic collections can contain only Objects.
« Prev item • Next item »

Comments

No one has put a bit in.

Leave comment

You must be logged in as a member to add comment to this blog