I was wondering if I already knew an object was a string if it was faster to cast it or to call ToString(). I thought it would be faster to call ToString() because casting has to do some type checking while the String class overrides ToString to return itself:
public class String { //... public override string ToString() { return this; } }
By this reasoning, I figured that (a is string && a.ToString().Length < 4000) would be cheaper than (a is string && ((string)a).Length < 4000).
It turns out they are both six IL instructions:
Calling ToString
L_0007: ldloc.0 L_0008: isinst string L_000d: brfalse.s L_0023 L_000f: ldloc.0 L_0010: callvirt instance string [mscorlib]System.Object::ToString() L_0015: callvirt instance int32 [mscorlib]System.String::get_Length()
Casting
L_0025: ldloc.0 L_0026: isinst string L_002b: brfalse.s L_0041 L_002d: ldloc.0 L_002e: castclass string L_0033: callvirt instance int32 [mscorlib]System.String::get_Length()
So… now what is the cost difference between the castclass operator and the virtual method call to the ToString method?
Turns out the cast takes about 75% of the time of a ToString call.
using System; static class Program { static void Main() { object o = "a string"; string a; string b; Boolean r = (o is string && o.ToString().Length < 4000); r = (o is string && ((string)o).Length < 4000); DateTime t = DateTime.Now; for (int i = int.MinValue; i < int.MaxValue; i++) a = (string)o; Console.WriteLine(DateTime.Now - t); t = DateTime.Now; for (int i = int.MinValue; i < int.MaxValue; i++) b = o.ToString(); Console.WriteLine(DateTime.Now - t); } }