Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does System.Array perform boxing on value types or not?

Tags:

arrays

c#

boxing

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>, and System.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)

like image 372
GazTheDestroyer Avatar asked Nov 21 '11 15:11

GazTheDestroyer


People also ask

What does boxing and unboxing have to do with Arraylists?

Unboxing extracts the value type from the object. Boxing is implicit; unboxing is explicit. I knew We can store any objects in an arraylist, because system. object is a base for all all types.

What are boxing and unboxing What are the performance implications?

Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. When the common language runtime (CLR) boxes a value type, it wraps the value inside a System. Object instance and stores it on the managed heap. Unboxing extracts the value type from the object.

Where do we use boxing and unboxing in C#?

Boxing and unboxing are important concepts in C#. The C# Type System contains three data types: Value Types (int, char, etc), Reference Types (object) and Pointer Types. Basically, Boxing converts a Value Type variable into a Reference Type variable, and Unboxing achieves the vice-versa.

What is system array class in C#?

The Array class is the base class for all the arrays in C#. It is defined in the System namespace. The Array class provides various properties and methods to work with arrays.


1 Answers

No using an array does not box if you use the indexer notation. e.g.

new int[2];
x=[1]=3;

Compiles to the following IL (note the line numbers are irrelevant as they come from some other snippet of code)

IL_0011: ldc.i4.2
IL_0012: newarr System.Int32
IL_0017: stfld Int32[] x
IL_001c: ldarg.0
IL_001d: ldfld Int32[] x
IL_0022: ldc.i4.1
IL_0023: ldc.i4.3
IL_0024: stelem.i4

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::

public int Get(int index)
public void Set(int index,int value)

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 or readonly when using a T[]. stelem.* type usually do not check type. E.g. using stelem.i4 is faster than using stelem.any Int32 unless you prefix it with readonly 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 a T[] 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.

like image 124
Michael B Avatar answered Oct 13 '22 08:10

Michael B