キャストとasのパフォーマンス
IBM Developer 日本語版 : 大変申し訳ありません。このページは無効です。
Javaの記事ですがキャストとinstanceofについての比較を行っています。ぱっと考えるとキャストは失敗すると例外が発生するのでinstanceofの方がよさそうに思ってしまいます。しかし、例外のコストは例外発生時なので、例えばキャストが失敗しないコレクションを対象とする場合は、instanceofの方がコストが掛かるという話らしい。なるほどなぁ〜とか思ってC#でもテストしてみました。
using System; using System.Collections; class Dog { } class MyDog : Dog { } class Cat { } class MyCat : Cat { } class Program { static void DogAs(ArrayList al) { for (int i = 0; i < al.Count; ++i) { Dog d = al[i] as Dog; } } static void DogCast(ArrayList al) { for (int i = 0; i < al.Count; ++i) { Dog d = (Dog)al[i]; } } static void DogCastWithTryCatch(ArrayList al) { for (int i = 0; i < al.Count; ++i) { try { Dog d = (Dog)al[i]; } catch (Exception) { } } } const int count = 10000000; static void Main(string[] args) { ArrayList al = new ArrayList(); // 継承なしクラス for (int i = 0; i < count; ++i) al.Add(new Dog()); DateTime t; t = DateTime.Now; DogAs(al); Console.WriteLine(DateTime.Now.Subtract(t)); t = DateTime.Now; DogCast(al); Console.WriteLine(DateTime.Now.Subtract(t)); t = DateTime.Now; DogCastWithTryCatch(al); Console.WriteLine(DateTime.Now.Subtract(t)); // 継承させたクラスを使用 al.Clear(); for (int i = 0; i < count; ++i) al.Add(new MyDog()); t = DateTime.Now; DogAs(al); Console.WriteLine(DateTime.Now.Subtract(t)); t = DateTime.Now; DogCast(al); Console.WriteLine(DateTime.Now.Subtract(t)); t = DateTime.Now; DogCastWithTryCatch(al); Console.WriteLine(DateTime.Now.Subtract(t)); Console.Read(); } } /* 結果 00:00:00.0781250 00:00:00.0937500 00:00:00.1406250 00:00:00.0781250 00:00:00.1406250 00:00:00.1875000 */
さて、結果はと言うと・・・asの圧勝です。この結果だけ見ると差はあんまりありませんが、これはすべてのキャストが成功するキャストにとって最も有利な条件なので。半数がキャスト失敗するケースでは52秒も掛かり、一方asは同タイム。やっぱ実験してみないと分からないものですね〜(^^;