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);
}
}