C# Unboxing Test

The C# programming language

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. To explore further, we examine some code and perform a benchmark.

Unboxing test using ArrayList versus List

Unbox int:   1296 ms
Generic int:  165 ms [faster]

Note: 10000 x 10000 iterations. Unboxing ints had a significant performance negative.

Example

Note

Here we see 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. It adds all the numbers in an ArrayList of 10,000 items 10,000 times, and the equivalent List<int> generic. You can experiment by adding some addition in the code to avoid JITting.

Unboxing benchmark program [C#]

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;
	}
    }
}
Performance optimization

Benchmark results. What was found is 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. Please see the figures at the top of this article.

Note: Previous versions of this article were incorrect in stating you can unbox objects, not just values. The MSIL in this article was verified to contain the "L_0015: unbox.any int32" instruction. I apologize for the error.

Are there advantages to unboxing?

Question and answer

Not except in rare cases. There is the possibility that generics may result in longer MSIL generated. However, I was unable to verify this, and the runtime gains here likely will overshadow any of that cost. There is also a difference between foreach and for with ArrayList.

Rico's Performance Quiz

Summary

We examined the some performance characteristics of unboxing integral types in the C# language. What we saw here is that generics are far faster than ArrayList on values such as int. My guideline is to always prefer generics unless the code has some quirk that may benefit from ArrayList.

Object Type
.NET