views:

153

answers:

6

The code I'm writing receives an ArrayList from unmanaged code, and this ArrayList will always contain one or more objects of type Grid_Heading_Blk. I've considered changing this ArrayList to a generic List, but I'm unsure if the conversion operation will be so expensive as to nullify the benefits of working with the generic list. Currently, I'm just running a foreach (Grid_Heading_Blk in myArrayList) operation to work with the ArrayList contents after passing the ArrayList to the class that will use it.

Should I convert the ArrayList to a generic typed list? And if so, what is the most efficient way of doing so?

+1  A: 

The biggest penalty you have using ArrayLists is boxing.

With generics you get:
1. compile time safety
2. generics extensions
3. remove this limitation of having everything in the list convert to type object.

Those are the advantages you get to using them. They're advantage, but if you have to re-populate the generic from the ArrayList, it may not be worth doing, especially if you are just looping through the list to get the objects.

Kevin
A: 

"Efficient" is not an either-or property. It is relative, just as a big mouse is probably not bigger than a small elephant.

It depends on what else you are doing.

Your mileage may vary, but in my experience, while ArrayList may be "slower" than List<T>, I have never been doing so little else that it was in any way noticeable.

That said, it is nice to have the compiler doing type-checking for me, and it is nice not having to cast things.

Mike Dunlavey
+1  A: 

I often use this checklist to evaluate questions like yours:

  1. Make it correct
  2. Make it clear
  3. Make it concise
  4. Make it efficient

List<Grid_Heading_Blk> is far more intention-revealing than ArrayList. So, without even considering efficiency, there is already a big win for item 2.

To convert an ArrayList to a List<>, you have to iterate over the ArrayList once and cast each element. The foreach is doing an implicit cast, so the overhead is only in the extra iteration.

Iterating a sequence twice takes the performance from O(n) to O(2n), which is still O(n) (magnitude, not value, is what matters for performance). Therefore, you can consider the change benign.

However, if literally all you are doing is running the foreach, you should just use ArrayList directly - changing it to List<> buys you no more expressive power.

Bryan Watts
A: 

If the objects are coming from unmanaged code, and you don't need to add or remove objects, then an array of Grid_Heading_Blk might be more efficient than a List. If you can get away with using an array, using a for loop might be slightly faster than foreach.

bbudge
+1  A: 

Why do you need to convert the ArrayList at all? To be honest, your foreach loop seems like it would do the trick. Yes, as Kevin says above the only penalty you'd be paying is unboxing - but as it stands it is pretty simple code and you probably don't have enough grid headings to pay a real performance hit.

But if you must convert it I would say, rather than writing your own for loop to convert to the List generic type, it might be better to use the constructor which takes IEnumerable type (something ArrayList should implement already.)

List<Grid_Heading_Blk> heading = new List<Grid_Heading_Blk>( arrayList );
WalterVonBruegemon
+1  A: 

Here's a stab at a performant way to create a generic list from an ArrayList.

List<Grid_Heading_Blk> myList = new List<Grid_Heading_Blk>(source.Count);
myList.AddRange(source.OfType<Grid_Heading_Blk>());

By calling the constructor that accepts an int, the backing storage is allocated only once.

As always, you should measure the performance using whatever tools you normally use.

David B
Thanks, everyone. Lots of good answers here. While performance/efficiency is certainly a key issue, I may have been undervaluing the readability provided by a typed structure. If someone else is eventually maintaining my code, I want it to be as clear as possible what I'm doing.
Greg