I recently did some rough performance measuring on List<>
vs []
for an array of small structures. System.Array seemed to win hands down so I went with that.
It's only just dawned on me that System.Array contains object types, so surely filling it with structures would cause boxing to occur?
However, the MSDN entry for System.Array states:
In the .NET Framework version 2.0, the Array class implements the
System.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
, andSystem.Collections.Generic.IEnumerable<T>
generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools. As a result, the generic interfaces do not appear in the declaration syntax for the Array class, and there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations).
Does this mean that boxing does not occur after all? (And would explain my performance results)
No using an array does not box if you use the indexer notation. e.g.
Compiles to the following IL (note the line numbers are irrelevant as they come from some other snippet of code)
For languages that cannot use the indexer (and I don't really know if they exist or not) 2 other methods are created at compile time for Arrays.
It creates these public methods::
Those methods don't box either and are not normally accessible through C#. (Don't ask me why they are public methods). You can execute them using IL or by creating delegates to them. They are slower as you are forced to do a callvirt to invoke these methods.
The stelem.* and ldelem.* family is used to handle storing to a strongly typed array type. When using generics usually the following prefixes are attached
constrained
orreadonly
when using aT[]
.stelem.*
type usually do not check type. E.g. usingstelem.i4
is faster than usingstelem.any Int32
unless you prefix it withreadonly
because otherwise it forces a type check.Now the typecheck is COMPLETELY useless on valuetype arrays are they are not covariant!
Because the runtime generates the one dimensional array starting at zero (either called SZ_array or vector type) type they are natively known.
There are a family of il op codes for them:
newarr
,stelem.*
,ldelem.*
,ldlen
etc.The
List<T>
type uses aT[]
for its backing store in the microsoft implementation of the BCL.List<T>
does not box. Regardless of using list or array you are storing things in an array.