I try to set List< int > value
List< int > a;
//...
a[i] = X;
ilspy shows that setting compiles to:
callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::set_Item(int32, !0)
But this code
int[] b;
//...
b[i] = Y;
compiles to
stelem.i4
And was faster in 7 times with my benchmark.
As I understand virtual call is more expensive than stelem. Is it possible to use List< T > with array perfomace
update
Code:
static void Main(string[] args)
{
int N = int.Parse(args[0]);
int M = int.Parse(args[1]);
var sw = new Stopwatch();
sw.Start();
int[] a = new int[N];
for (int k = 0; k < M; ++k)
{
for (int i = 0; i < N; ++i)
{
a[i] = i * 2;
a[i] -= i;
a[i] += 1;
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds + ":" + a[N - 1]);
var b = new List<int>(N);
for (int i = 0; i < N; ++i)
{
b.Add(0);
}
sw.Restart();
for (int k = 0; k < M; ++k)
{
for (int i = 0; i < N; ++i)
{
b[i] = i * 2;
b[i] -= i;
b[i] += 1;
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds + ":" + b[N - 1]);
}
Run and output:
> ./Console.exe 1000000 100
166:1000000
1467:1000000
No.
List<T>
wraps an array, and it has some necessary overhead (in the first place because it is a class). Also operations like inserting and deleting are costly, specifically when it causes to reorder all other elements in the list.
If you don't want the overhead of List<T>
or need the features like it's dynamic size, inserting and deleting, use an array. If you want or need to use List<T>
, accept the performance loss.
You will have a hard time writing more efficient code than the .NET BCL team did, especially when it comes to re-sizing the array and other operations that can benefit from direct access to the underlying memory / OS functions.
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