How Generics save from Boxing

Total: 6 Average: 3.7

At the method input, we often perform a null test. Someone makes the test as a separate method, so that the code looks cleaner, and gets something like this:

The interesting thing about this test is that I see a frequent use of the object attribute, though you can use generic. Let’s try to replace our method with generic and compare performance.

Before testing, you need to take into account another drawback of the object argument. Value types can never be null (Nullable type is not counted). Calling a method like ThrowIfNull(5) is meaningless, but since the type of the argument is object, the compiler will call the method. As for me, this reduces the quality of the code, which in some situations is much more important than performance. In order to get rid of this behavior and to improve the signature of the method, the generic method will have to be divided into two, with constraints. The trouble is that you can not specify a Nullable constraint, however, you can specify the nullable argument, with the struct constraint.

Let’s start testing the performance and use the BenchmarkDotNet library. Attach attributes, run, and look at the results.

Method Mean Error StdDev
CallMethodWithObjArgString 1.784 ns 0.0166 ns 0.0138 ns
CallMethodWithObjArgNullableInt 124.335 ns 0.2480 ns 0.2320 ns
CallMethodWithGenericArgString 1.746 ns 0.0290 ns 0.0271 ns
CallMethodWithGenericArgNullableInt 2.158 ns 0.0089 ns 0.0083 ns

Our generic showed 100 times faster performance on the nullable type! All this is because of the boxing. When we call CallMethodWithObjArgNullableInt, our nullable-int is being “boxed” and placed in the heap. Boxing is a very expensive operation, that’s why the performance of the method is down. So, we can avoid boxing using generic.

Thus, the generic argument is better than the object because it:

  1. Saves from boxing
  2. Improves the method signature by using constraints

Nikolay Zdravkov

A .NET developer. Nikolay has skills in ASP.NET Web Api, MVC, EntityFramework, Dapper, SQLServer.

Latest posts by Nikolay Zdravkov (see all)