[.NET] typeof, GetTypeでパフォーマンスが悪くなるか

typeof, GetTypeでパフォーマンスが悪くなるか

GetTypeやtypeofなどオブジェクトの情報を取得する関数、メソッドでパフォーマンスが悪化するかどうかを調べる必要があって調べてみた。
typeofは演算子でありGetTypeはObject型のインスタンスメソッド。

stackoverflow.comにあった2年ぐらい前のエントリでは、テストプログラムを書いて実験している。このテストプログラムのコードにいろいろつっこみが入っている様子が楽しい。
Performance of Object.GetType()
http://stackoverflow.com/questions/353342/performance-of-object-gettype
質問者は「遅くなる」と確認しているのではなく、「遅いかもしれない」と心配している状態で、実際に性能劣化があったわけではないようだ。

テスト結果によると、100万回で1秒前後しか変わらない。1秒「も」違うのか、という人もいるかもしれないが、他の処理(たとえば、I/O)の方が影響が大きいのでは、ということに。

2005年のMSDNの記事
Dodge Common Performance Pitfalls to Craft Speedy Applications
http://msdn.microsoft.com/en-us/magazine/cc163759.aspx
当時の.NETは 2.0なのでその後最適化が図られた部分はあるだろう。
かといって速くなっているとは限らないが。

ここではreflection taskで重いもの軽いものを分類している。これによるとtypeof, GetTypeは両方とも軽い。
以下がlightweightとされているもの。

typeof
Object.GetType
typeof == Object.GetType
Type equivalence APIs (including typehandle operator overloads)
get_Module
get_MemberType
Some of the IsXX predicate APIs
New token/handle resolution APIs in the .NET Framework 2.0

逆に、heavyなのは

GetXX  APIs (MethodInfo, PropertyInfo, FieldInfo, and so on)
GetCustomAttributes
Type.InvokeMember
Invoke APIs (MethodInfo.Invoke, FieldInfo.GetValue, and so on)
get_Name (Name property)
Activator.CreateInstance

一方、これとは逆に、GetTypeやtypeofでオブジェクト情報を取得するのは遅いというblogもある。

Drilling into .NET Runtime microbenchmarks: ‘typeof’ optimizations.
http://blogs.msdn.com/b/vancem/archive/2006/10/01/779503.aspx

ここでは

System.Type myType = typeof(string); // in real life not a literal
// and then in other methods (and maybe in a loop)
if (anObj.GetType() == myType) { /* some op */ }

と同じこと(type比較チェック)をする方法を紹介している。この方法では別の型RuntimeTypeHandleを使う。

RuntimeTypeHandle myType = typeof(string).TypeHandle;
// and then in other methods (and maybe in a loop)
if (Type.GetTypeHandle(anObj).Equals(myType)) { /* some op */ }

一行目はJITの最適化によりテーブルから値を引くコードになるので速く、3行目もSystem.Typeオブジェクトを生成しないのでやや速い、とのことだ。2つのソースコードのうち、前者のtypeofやGetTypeは、”is”演算子よりも一桁遅いと著者は書いている。

おそらく最初のstackoverflowのエントリの質問者もオブジェクト生成による性能劣化が激しいことを危惧しての質問だったのだと思う。この発想は技術的には正しい(小さいとしても時間はかかっているはず)。

結論から言うと、 非常に多くのtype比較があればこの方法によって性能の違いを体感できるのだろうが、実際には非効率なコードがあちこちにちらばっているのでこのような細かいものをつぶすことは大きな影響はないことがおおいだろう。

大山鳴動鼠がなんとか、、という気がしないでもないが、今回の調べ物でJITの話やreflectionに少し詳しくなったという成果はあった。

広告

コメントを残す

コメントを投稿するには、以下のいずれかでログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。