Well, you probably won't notice a difference, so your old way with loops is perfectly fine. But with way 1 you can save few lines of code. List.AddRange
can indeed be a little bit more efficient because it can initialize the list (and the underlying storage which is an array) with the correct size when you pass a type which is a collection(has a Count
property). If the array is not initialized with the correct size it must be resized in the loop.
You can see the optimization approach in the source(InsertRange
called from AddRange
):
public void InsertRange(int index, IEnumerable<T> collection) {
// ...
ICollection<T> c = collection as ICollection<T>;
if( c != null ) { // if collection is ICollection<T>
// this is the optimzed version if you use AddRange with a list
int count = c.Count;
if (count > 0) {
EnsureCapacity(_size + count);
if (index < _size) {
Array.Copy(_items, index, _items, index + count, _size - index);
}
// If we're inserting a List into itself, we want to be able to deal with that.
if (this == c) {
// Copy first part of _items to insert location
Array.Copy(_items, 0, _items, index, index);
// Copy last part of _items back to inserted location
Array.Copy(_items, index+count, _items, index*2, _size-index);
}
else {
T[] itemsToInsert = new T[count];
c.CopyTo(itemsToInsert, 0);
itemsToInsert.CopyTo(_items, index);
}
_size += count;
}
}
else {
// this is the loop version that you use
using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Insert(index++, en.Current);
}
}
}
_version++;
}