This question has already been answered well, however so far it has been missing hard numbers.
Over 100000000 iterations
AS : Failure 00:00:00.9282403
Cast : Failure 00:00:00.9868966
AS : Success 00:00:00.9350227
Cast : Success 00:00:01.1382759
The figures consistently come back in these proportions
I want to point out that the only conclusion to take from these figures is that from a performance point of view, there is very little to be gained by choosing one of these methods over the other. There's a very little in the difference for a single call (where very little tends to zero). That said, "as" is faster :)
After that, the above figures mostly stand to reason.
"As" takes longer on failure than it does on success. On success nothing happens, the value can be used as is, or simply copied. On failure it requires a jump to copy a null reference.
"Cast" is faster on failure, one call to "is" and it doesn't do any more. On success it's much slower, it has the over head of the call to "is" and then the cast.
However I'm surprised that Cast on failure takes longer than AS failure
Edit
As requested, figures for cast in a try / catch block
Over 100000000 iterations
Catch : Failure 05.05:00:00 // approximately, because I didn't hang around
Catch : Success 00:00:01.4000952
The code that produced the first set of figures
class Program
{
const int ITERATION_COUNT = 100000000;
private static UInt64 stringCount = 0;
private static UInt64 objectCount = 0;
static void Main(string[] args)
{
Console.WriteLine("Over {0} iterations ", ITERATION_COUNT);
string s = "Hello";
object o = new Int32();
RunTest("AS : Failure {0}", TestAs, o);
RunTest("Cast : Failure {0}", TestIs_And_Cast, o);
RunTest("AS : Success {0}", TestAs, s);
RunTest("Cast : Success {0}", TestIs_And_Cast, s);
Console.WriteLine("Press any key to stop");
Console.ReadKey();
}
private static void RunTest(string testDescription, Action<object> testToRun, object arg)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < ITERATION_COUNT; i++)
testToRun(arg);
sw.Stop();
Console.WriteLine(testDescription, sw.Elapsed);
}
static void TestAs(object obj)
{
string s = obj as string;
if (s != null)
stringCount++;
else
objectCount++;
}
static void TestIs_And_Cast(object obj)
{
string s = null;
if (obj is string)
{
s = (string)obj;
stringCount++;
}
else
objectCount++;
}
}