C# Unboxing (Use ints in ArrayList)

Understand unboxing on ArrayList. Test List which does not require unboxing.
Unboxing reduces performance on collections. It requires a value that was boxed inside an object reference to be taken out of that container. Boxing and unboxing are known to be slow. We examine some code and perform a benchmark.
Example. Here we use a short benchmarking program. The test performed satisfies several criteria. First, it measures time unboxing. This is important because reading values is more frequent than writing values.

Note: It adds all the numbers in an ArrayList of 10,000 items 10,000 times, and the equivalent List<int> generic.


Tip: You can experiment by adding some addition statements in the code to avoid JITting.

C# program that tests unboxing using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; class Program { static void Main() { // Populate lists for (int i = 0; i < 10000; i++) { _arr1.Add(0); _list1.Add(0); } const int m = 10000; Stopwatch s1 = new Stopwatch(); s1.Start(); for (int i = 0; i < m; i++) // Unboxing { U1(); } s1.Stop(); Stopwatch s2 = new Stopwatch(); s2.Start(); for (int i = 0; i < m; i++) // No unboxing { R1(); } s2.Stop(); Console.WriteLine("{0},{1}", s1.ElapsedMilliseconds, s2.ElapsedMilliseconds); Console.Read(); } static ArrayList _arr1 = new ArrayList(); static List<int> _list1 = new List<int>(); static void U1() { // Unboxing foreach (object i in _arr1) { int v = (int)i; } } static void R1() { // None foreach (int i in _list1) { int v = i; } } } Output Unbox int: 1296 ms Generic int: 165 ms [faster] Iterations: 10000 * 10000
We see that unboxing caused a performance loss over the generic collections. My measurements of time unboxing were nearly ten times higher than the version without boxing. Value type instances were made faster with generics.

Note: Previous versions of this article were incorrect in stating you can unbox objects, not just values.

So: The MSIL in this article was verified to contain the "L_0015: unbox.any int32" instruction. I apologize for the error.

Advantages. Boxing typically has no advantages. There is the possibility that generics may result in longer MSIL generated. But I was unable to verify this, and the runtime gains here likely will overshadow any of that cost.

Also: There is a difference between foreach and for with ArrayList. This is an older, slower collection than List.

Summary. We examined the some performance characteristics of unboxing integral types. Generics are far faster than ArrayList on values such as int. I always prefer generics unless the code has some quirk that may benefit from ArrayList.
© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to
Dot Net Perls