这个问题已经得到了很好的回答,但是目前缺少硬性数据。
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
这些数字始终保持这些比例。
我想指出的是,从性能角度来看,唯一的结论是选择其中一种方法并没有太多好处。对于单个调用来说,差异很小(非常接近零)。尽管如此,“as”更快 :)
在此之后,上述数字大多是合理的。
“as”在失败时需要比成功时花费更长的时间。成功时什么也不会发生,该值可以直接使用或者简单地复制。失败时,它需要跳转以复制空引用。
“Cast”在失败时更快,只需一次“is”调用即可完成。但是在成功时,它要慢得多,因为需要调用“is”,然后再进行强制转换。
但是我很惊讶Cast在失败时需要的时间比AS失败还长。
编辑
按照要求,在try / catch块中添加了cast的数字。
Over 100000000 iterations
Catch : Failure 05.05:00:00 // approximately, because I didn't hang around
Catch : Success 00:00:01.4000952
生成第一组图形的代码。
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++;
}
}