Compact Frameworkで高速なインスタンス生成 ただし実験失敗
あまり細かいパフォーマンスをどうこう言うのは趣味ではないし、実験も失敗しているんですが、まあちょっと試した内容をメモしておきます(・ω・)
前提
- リフレクションは遅い
- Compact FrameworkではSystem.Reflection.Emitはサポートされない
実験
っで、Compact Frameworkでも使える方法で、高速なインスタンスの生成方法ってどんな方法があるかな〜と思い、以下のような方法を考えてみたんですが(・ω・)
public class Hoge { ... }
public class TypeUtility { public static T DefaultConstructor<T>() where T : new() { return new T(); } public static Func<T> GetConstructor<T>() { MethodInfo mi = typeof(TypeUtility).GetMethod( "DefaultConstructor" ); mi = mi.MakeGenericMethod( typeof(T) ); return (Func<T>)Delegate.CreateDelegate( typeof(Func<T>), null, mi ); } }
PC(自分の開発機)とWindows Mobile(DT-5300)を用意して。
呼び出し速度の比較対象として、Activator.CreateInstance()、ConstructorInfo.Invoke()、System.Reflection.Emitを使ってdelegateを作成する方法(PCのみ)、直接newする方法で、インスタンスの生成速度を測ってみたんですが。
その結果は以下のようになりました。
PC 1,000,000回 | WM 100,000回 | |
---|---|---|
Activator.CreateInstance() | 2142 ms | 6425 ms |
ConstructorInfo.Invoke() | 3139 ms | 2164 ms |
TypeUtility.GetConstructor() | 784 ms | 6820 ms |
System.Reflection.Emit | 14 ms | - |
direct new | 8 ms | 67 ms |
先にPCの方を見ると、TypeUtility.GetConstructor()の方法はActivator.CreateInstance() 2142 ms、ConstructorInfo.Invoke() 3139 msに比べて784 msと一応高速にはなっていますが。
でも、想像していたほど速くはなくて(´・ω・`)
Windows Mobileの方を見ると、TypeUtility.GetConstructor()の方法はActivator.CreateInstance()よりも遅くなっていますね(´д`;)
あと、Full FrameworkとCompact Frameworkでは、ConstructorInfo.Invoke()とActivator.CreateInstance()の速度が逆転していますね(・ω・)
ちなみに、この傾向はWM実機だけでなくPC上のエミュレータで確認しても同じでした。
っで、それにしてもTypeUtility.GetConstructor()は遅くね(゚Д゚)?、っということで、代わりに以下の処理を呼び出してみたところ、Compact Frameworkで116 msと十分な速度になってくれました。
public class TypeUtility { public static Hoge HogeConstructor() { return new Hoge(); } public static Func<Hoge> GetConstructor() { MethodInfo mi = typeof(TypeUtility).GetMethod( "HogeConstructor" ); return (Func<Hoge>)Delegate.CreateDelegate( typeof(Func<Hoge>), null, mi ); } }
これって、MethodInfo.MakeGenericMethod()の返すMethodInfoの処理が遅いってこと(・ω・)?