BLOG
02 November 2022

The Magic of Casting - Infrastructure, Options and Benchmarking

tech

We all cast. Unfortunately, I’m not referring to spells. That would be awesome, of course, but I’m talking about programming and casting from one type to another. Have you ever thought about the differences between them? You most likely did. However, have you measured their speed? I'm willing to bet you didn't. If so, you've come to the right place, because that is exactly what we intend to do. Without further ado, Let's get started. 

Infrastructure  

To test and to benchmark we need something to work with. None of you will be surprised when I tell you that we are going to work with a simple class. Just like that one.   

 

As you can see, class is nothing out of the ordinary. Only a few fields are required to give us something to work with. We need a provider class now that we have a POCO class. When it comes to benchmarking operations on objects, this is the preferred method. Because benchmark requires object initialization. This is how the provider class should look: 

 

Provider has three properties. BlogData – is an object type fields that holds an instance on BlogData class. NotBlogData - is an object type fields that holds an anonymous object. BlogDataList - a list of object types that are instances of BlogData. 

Casting options

Before we begin benchmarking, we must discuss casting options. The first option is a hard cast. The code as well as the result look like this: 

 

This is the simplest way of casting and when an object can be cast, everything works perfectly – but let's see what happens if the object cannot be cast. 

In this case, we get an InvalidCastException . When codding in this manner, we must keep this in mind. 

The safe cast option comes in second. It employs the "as" keyword and reads as follows.  

If we try to safe cast an object that can’t be casted the resulted object will be a null. This also needs to be considered when using this kind of casting. If the casting is possible, there will be no problem. 

 

Last but not least, we can consider the match cast. In this case, we check to see if something is of a type, and if it is, the result of successful casting is stored in a variable, and the if statement follows. Option that is both elegant and readable. 

    

Benchmarking Round 1 – Single Object  

Now that we've seen all of the basic casting approaches, it's time to see how they perform. Benchmarking, as we all know, is the process of comparing the performance of various solutions. In this case, we'll be utilising an excellent Nuget Package called BenchmarkDotNet. The documentation and code for the solution can be found here. I strongly advise you to familiarise yourself with it. 

We need a code to benchmark now that we have the tool. In this case, we want to compare the various options for casting a single object. 

As you can see, the only work that needed to be done was to incorporate the code for successful casting options into methods and to add benchmarking arguments. To run this code, switch the application to Release mode and execute it. 

After a few minutes, around 2-3 in my case, the results are back 

They're intriguing but not particularly surprising. We probably all had a gut feeling that hard cast would be the quickest. So there's no surprise there. What surprised me was the magnitude of how much faster it is. We're talking 22 and 28 times faster, respectively. That is very impressive and should be taken into account when coding. 

 

The Challenge

Finally, the fun begins. Because when is came to a single object the casting options are straight forward rally. With the collection, not so much. I’m sure you remember that inside our objects provides there in an option to get collection of objects. 

  

I have a challenge for you right now: write a method that takes this Listobject> and returns the ListBlogData> . Make it as fast as possible. When you've done that, keep reading and compare your method to the ones that will be presented. 

 

Benchmarking Round 2 – Collections of objects 

If you haven't already, please do so now that you've created your method. I'll show you the options we'll be considering. After you've finished looking, run a BenchmarkListCastMethods benchmark. 

The results are here, and they are surprising. There are two things worth noticing. One, the difference are not so vast. The slowest time is 27 microseconds, and the fastest time is 10 microseconds. What was the quickest method is more interesting. GetByHardTypeOf was the quickest. We used the formula x => x. GetType() == typeof(BlogData)) to determine whether an object can be casted and hard casting to perform actual casting. 

Summary  

We have just looked into the majority of the casting possibilities, and the distinctions are clearly visible. Please keep them in mind as you code, as they might turn out to be useful to you. 

If you have any questions, please drop me a line at karol.rogowski@softwarehut.com. 

Till the next time. Keep coding. 

 

 


Author
Karol Rogowski
Head Of Engineering

Working in IT since 2009. Currently working as Head of Engineering at SoftwareHut and as an academic teacher at Białystok Technical University. Co-founder of meet.js Białystok. Book and articles author. Father, husband, huge H.P. Lovecraft fan and terrible poker player.