I require a fast speed in processing my page. The count of the values to be added will be dynamic.
Which one of the above is preferred? Support with a valid reason.
Edit: For eg:
string str = "a,b,c"; //Count of the number of elements in str is not fixed
string[] arr = str.Split(',');
or,
ArrayList al = new ArrayList();
al.Add(str.Split(','));
An array is faster and that is because ArrayList uses a fixed amount of array. However when you add an element to the ArrayList and it overflows. It creates a new Array and copies every element from the old one to the new one.
Conclusion: set operations on arrays are about 40% faster than on lists, but, as for get, each set operation takes a few nanoseconds - so for the difference to reach 1 second, one would need to set items in the list/array hundreds of millions of times!
The array is faster in case of access to an element while List is faster in case of adding/deleting an element from the collection.
In general, one would opt for using Lists (List) due to their flexibility in size. On top of that, msdn documentation claims Lists use an array internally and should perform just as fast (a quick look with Reflector confirms this).
List<T>
should generally be preferred over ArrayList
If you want lists you expose to callers to be immutable, this is supported by both List<T>
and ArrayList
:
List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);
Your question asks about choosing between ArrayList
and List<T>
, but your example shows an array, which is neither.
Array for "immutable" collections,
List<T>
for mutable collections.
Performance stats (Array vs List vs ReadonlyCollection):
Array List ReadOnlyCollection Penalties Method
00:00:01.3932446 00:00:01.6677450 00:00:06.2444633 1 vs 1,2 vs 4,5 Generate
00:00:00.1856069 00:00:01.0291365 00:00:02.0674881 1 vs 5,5 vs 11,1 Sum
00:00:00.4350745 00:00:00.9422126 00:00:04.5994937 1 vs 2,2 vs 10,6 BlockCopy
00:00:00.2029309 00:00:00.4272936 00:00:02.2941122 1 vs 2,1 vs 11,3 Sort
Source code:
interface IMethods<T>
{
T Generate(int size, Func<int, int> generator);
int Sum(T items);
T BlockCopy(T items);
T Sort(T items);
}
class ArrayMethods:IMethods<int[]>
{
public int[] Generate(int size, Func<int, int> generator)
{
var items = new int[size];
for (var i = 0; i < items.Length; ++i)
items[i] = generator(i);
return items;
}
public int Sum(int[] items)
{
int sum = 0;
foreach (var item in items)
sum += item;
return sum;
}
public int[] BlockCopy(int[] items)
{
var res = new int[items.Length / 2];
Buffer.BlockCopy(items, items.Length / 4 * sizeof(int), res, 0, res.Length * sizeof(int));
return res;
}
public int[] Sort(int[] items)
{
var res = new int[items.Length];
Buffer.BlockCopy(items, 0, res, 0, items.Length * sizeof(int));
return res;
}
}
class ListMethods : IMethods<List<int>>
{
public List<int> Generate(int size, Func<int, int> generator)
{
var items = new List<int>(size);
for (var i = 0; i < size; ++i)
items.Add(generator(i));
return items;
}
public int Sum(List<int> items)
{
int sum = 0;
foreach (var item in items)
sum += item;
return sum;
}
public List<int> BlockCopy(List<int> items)
{
var count = items.Count / 2;
var res = new List<int>(count);
var start = items.Count / 4;
for (var i = 0; i < count; ++i)
res.Add(items[start + i]);
return res;
}
public List<int> Sort(List<int> items)
{
var res = new List<int>(items);
res.Sort();
return res;
}
}
class ReadOnlyCollectionMethods:IMethods<ReadOnlyCollection<int>>
{
public ReadOnlyCollection<int> Generate(int size, Func<int, int> generator)
{
return new ReadOnlyCollection<int>(Enumerable.Range(0, size).Select(generator).ToList());
}
public int Sum(ReadOnlyCollection<int> items)
{
int sum = 0;
foreach (var item in items)
sum += item;
return sum;
}
public ReadOnlyCollection<int> BlockCopy(ReadOnlyCollection<int> items)
{
return new ReadOnlyCollection<int>(items.Skip(items.Count / 4).Take(items.Count / 2).ToArray());
}
public ReadOnlyCollection<int> Sort(ReadOnlyCollection<int> items)
{
return new ReadOnlyCollection<int>(items.OrderBy(s => s).ToList());
}
}
static class Program
{
static Tuple<string, TimeSpan>[] CheckPerformance<T>(IMethods<T> methods) where T:class
{
var stats = new List<Tuple<string, TimeSpan>>();
T source = null;
foreach (var info in new[]
{
new {Name = "Generate", Method = new Func<T, T>(items => methods.Generate(10000000, i => i % 2 == 0 ? -i : i))},
new {Name = "Sum", Method = new Func<T, T>(items => {Console.WriteLine(methods.Sum(items));return items;})},
new {Name = "BlockCopy", Method = new Func<T, T>(items => methods.BlockCopy(items))},
new {Name = "Sort", Method = new Func<T, T>(items => methods.BlockCopy(items))},
new {Name = "Sum", Method = new Func<T, T>(items => {Console.WriteLine(methods.Sum(items));return items;})},
}
)
{
int count = 10;
var stopwatch = new Stopwatch();
stopwatch.Start();
T res = null;
for (var i = 0; i < count; ++i)
res = info.Method(source);
stopwatch.Stop();
source = res;
stats.Add(new Tuple<string, TimeSpan>(info.Name, stopwatch.Elapsed));
}
return stats.ToArray();
}
static void Main()
{
var arrayStats = CheckPerformance(new ArrayMethods());
var listStats = CheckPerformance(new ListMethods());
var rcStats = CheckPerformance(new ReadOnlyCollectionMethods());
Console.WriteLine(" Array List ReadOnlyCollection Penalties Method");
for(var i = 0; i < arrayStats.Length; ++i)
{
Console.WriteLine("{0} {1} {2} 1 vs {3,4:f1} vs {4,4:f1} {5}", arrayStats[i].Item2, listStats[i].Item2, rcStats[i].Item2,
listStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds,
rcStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds, arrayStats[i].Item1);
}
}
List <T>
is always gonna be faster than an arrayList. List <T>'s
dont have to box the values that are added to them.
ArrayList
only "accept" objects, so that means that while you can add any object you want to the list, it will have to be boxed (implicitly by the CLR) and then it has to be unboxed again (explicitly by you) when you need the values.
edit: here is a nice link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With