views:

2178

answers:

12

The system I work on here was written before .net 2.0 and didn't have the benefit of generics. It was eventually updated to 2.0, but none of the code was refactored due to time constraints. There are a number of places where the code uses ArraysLists etc. that store things as objects.

From performance perspective, how important change the code to using generics? I know from a perfomance perspective, boxing and unboxing etc., it is inefficient, but how much of a performance gain will there really be from changing it? Are generics something to use on a go forward basis, or it there enough of a performance change that a conscience effort should be made to update old code?

+4  A: 

The only way to know for sure is to profile your code using a tool like dotTrace.

http://www.jetbrains.com/profiler/

It's possible that the boxing/unboxing is trivial in your particular application and wouldn't be worth refactoring. Going forward, you should still consider using generics due to the compile-time type safety.

Ben Hoffstein
A: 

The biggest gains, you will find in Maintenance phases. Generics are much easier to deal with and update, without having to deal with conversion and casting issues. If this is code that you continually visit, then by all means take the effort. If this is code that hasn't been touched in years, I wouldn't really bother.

hova
+1  A: 

It depends, the best answer is to profile your code and see. I like AQTime but a number of packages exist for this.

In general, if an ArrayList is being used a LOT it may be worth switching it to a generic version. Really though, it's most likely that you wouldn't even be able to measure the performance difference. Boxing and unboxing are extra steps but modern computers are so fast that it makes almost no difference. As an ArrayList is really just an normal array with a nice wrapper, you would probably see much more performance gained from better data structure selection (ArrayList.Remove is O(n)!) than with the conversion to generics.

Edit: Outlaw Programmer has a good point, you will still be boxing and unboxing with generics, it just happens implicitly. All the code around checking for exceptions and nulls from casting and "is/as" keywords would help a bit though.

Rick Minerich
A: 

What does autoboxing/unboxing have to do with generics? This is just a type-safety issue. With a non-generic collection, you are required to explicitly cast back to an object's actual type. With generics, you can skip this step. I don't think there is a performance difference one way or the other.

Outlaw Programmer
Look into documentation on generics and their usefulness when using structs, and you will see what boxing has to do with it. (Hint: you cannot get an object pointer to a stack variable)
Guvante
A: 

My old company actually considered this problem. The approach we took was: if it's easy to refactor, do it; if not (i.e. it will touch too many classes), leave it for a later time. It really depends on whether or not you have the time to do it, or whether there are more important items to be coding (i.e. features you should be implementing for clients).

Then again, if you're not working on something for a client, go ahead and spend time refactoring. It'll improve readability of the code for yourself.

echoblaze
+3  A: 

Generics, whether Java or .NET, should be used for design and type safety, not for performance. Autoboxing is different from generics (essentially implicit object to primitive conversions), and as you mentioned, you should NOT use them in place of a primitive if there is to be a lot of arithmetic or other operations which will cause a performance hit from the repeated implicit object creation/destruction.

Overall I would suggest using going forward, and only updating existing code if it needs to be cleaned up for type safety / design purposes, not performance.

Pete
+9  A: 

Technically the performance of generics is, as you say, better. However, unless performance is hugely important AND you've already optimised in other areas you're likely to get MUCH better improvements by spending your time elsewhere.

I would suggest:

  • use generics going forward.
  • if you have solid unit tests then refactor to generics as you touch code
  • spend other time doing refactorings/measurement that will significantly improve performance (database calls, changing data structures, etc) rather than a few milliseconds here and there.

Of course there's reasons other than performance to change to generics:

  • less error prone, since you have compile-time checking of types
  • more readable, you don't need to cast all over the place and it's obvious what type is stored in a collection
  • if you're using generics going forward, then it's cleaner to use them everywhere
Rory
A: 

Depends on how much is out there in your code. If you binding or display large lists in the UI, you would probably see a great gain in performance.

If your ArrayList are just sprinkled about here and there, then it probably wouldn't be a big deal to just get it cleaned up, but also wouldn't impact overall performance very much.

If you are using a lot a ArrayLists throughout your code and it would be a big untertaking to replace them (something that may impact your schedules), then you could adopt a if-you-touch-it-change-it approach.

Main thing is, though, that Generics are a lot easier to read, and are more stable across the app due to the strong typing you get from them. You'll see gains not just from performance, but from code maintainablity and stability. If you can do it quickly, I'd say do it.

If you can get buy-in from the Product Owner, I'd recommend getting it cleaned up. You love your code more afterward.

Tom Carr
A: 

If the entities in the ArrayLists are Object types, you'll gain a little from not casting them to the correct type. If they're Value types (structs or primitives like Int32), then the boxing/unboxing process adds a lot of overhead, and Generic collections should be much faster.

Here's an MSDN article on the subject

Mark Bessey
+3  A: 

Here's the results I got from a simple parsing of a string from a 100KB file 100,000 times. The Generic List(Of char) took 612.293 seconds to go 100,000 times through the file. The ArrayList took 2,880.415 seconds to go 100,000 times through the file. This means in this scenario (as your mileage will vary) the Generic List(Of char) is 4.7 times faster.

Here is the code I ran through 100,000 times:

Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
    Dim genList As New ArrayList

    For Each ch As Char In strToProcess.ToCharArray
        genList.Add(ch)
    Next

    Dim dummy As New System.Text.StringBuilder()
    For i As Integer = 0 To genList.Count - 1
        dummy.Append(genList(i))
    Next

End Sub

 Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
     Dim genList As New List(Of Char)

     For Each ch As Char In strToProcess.ToCharArray
         genList.Add(ch)
     Next

     Dim dummy As New System.Text.StringBuilder()
     For i As Integer = 0 To genList.Count - 1
         dummy.Append(genList(i))
     Next
 End Sub
torial
A: 

Generics has much better performance especially if you'll be using value-type (int, bool, struct etc.) where you'll gain a noticeble performance gain.

  1. Using Arraylist with value-types causes boxing/unboxing which if done several hundred times is substantialy slower then using generic List.

  2. when storing value-types as object you'll up to four time memory per item. While this amount won't drain your RAM the cache memory that is smaller could contain less items, Which means that while iterating a long collections there would be many copies from the main memory to the cache that would slow your application.

I wrote about here.

Dror Helper
Your application logic was flawed. Specifically, InsertItemsToList has the stopper.Start() misplaced. It needs to be inside the loop. Additionally, the performance difference when using a List<> of objects vs an ArrayList of objects is minimal - about a 10% speed boost (my numbers were 1.982 / 1.81 / 1.233 / 1.089). Admittedly, the performance boost for List<> vs ArrayList is very tangible for int, it's just not there for classes.
JustLoren
@JustLoren - Even without the minor "fault" the calculation are about the same. And I wrote both in my answer (above) and in the blog post the performance difference is mostly because of value-type boxing/unboxing
Dror Helper
A: 

Using generics should also mean that your code will be simplier and easy to use if you want to leverage things like linq in the later c# versions.

simonjpascoe