Is converting this ArrayList to a Generic List efficient?
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开发者_如何学Python. 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?
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.
I often use this checklist to evaluate questions like yours:
- Make it correct
- Make it clear
- Make it concise
- 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.
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 );
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.
"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.
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.
You can filter all elements of arrayList that can be cast to the same type using Enumerable.OfType(Of TResult) Method
List<MyClass> typedList = arrayList.OfType<MyClass>().ToList();
(based on suggestion in http://www.codeproject.com/Tips/68291/Convert-ArrayList-to-a-Generic-List )
精彩评论