少し前に、PC上でのIoCコンテナのパフォーマンス調査を行いました。
今回はXamarin上で調査しましたので、その情報を共有したいと思います。
それでまずは結果から見てみましょう。
まずはUnityの性能を100%としたときの評価グラフです。
具体的な数値は以下のとおりです。
Container | Singleton - Registartion | Singleton - Resolve | Transient - Registartion | Transient - Resolve |
---|---|---|---|---|
DryIoc | 75% | 1169% | 385% | 2255% |
SimpleInjector | 69% | 527% | 7% | 2231% |
AutoFac | 64% | 104% | 19% | 184% |
AutoFac Lambda | 96% | 110% | 5% | 1236% |
Unity | 100% | 100% | 100% | 100% |
SimpleInjectorは相変わらず早いですが、DryIocが素晴らしい速度を出していますね。
というわけで、詳細なデータを掘り下げてみて行ってみましょう。
前提条件
- iPhone 6S
- iOS 10.2
- Xamarin 4.2.2.11
- Xamarin.Forms 2.3.3.180
評価内容
- Singlton時のコンテナ登録時間
- Singlton時のインスタンス取得時間(10万インスタンス)
- インスタンス都度生成時のコンテナ登録時間
- インスタンス都度生成時のインスタンス取得時間(10万インスタンス)
評価結果
以下が評価結果です。
数値はミリ秒になります。
それぞれResolveは10万回実行しています。
Container | Singleton - Registartion[ms] | Singleton - Resolve[ms] | Transient - Registartion[ms] | Transient - Resolve[ms] |
---|---|---|---|---|
new Operator | 0.17 | 21.72 | 0.03 | 215.25 |
DryIoc | 21.07 | 22.61 | 0.17 | 1557.74 |
SimpleInjector | 23.01 | 50.18 | 9.07 | 1574.58 |
AutoFac | 24.86 | 253.96 | 3.56 | 19090.53 |
AutoFac Lambda | 16.51 | 241.12 | 13.64 | 2842.19 |
Unity | 15.86 | 264.31 | 0.67 | 35124.85 |
ざっくり分けると性能的には
- 第一集団
- DryIoc
- SimpleInjector
- 第二集団
- AutoFac Lambda
- Unity
になります。
さて、PC上での場合性能差ははっきりいってほとんど人にとって趣味のレベルでしたが、Xamarin上だと少しきにかかります。
今回は10万回のResolveでテストしました。
生成しているオブジェクトは13種類です。
この時、Unityの都度生成が0.35秒、AutoFacの非Lamdaが0.19秒かかっています。
ケースによっては性能が気になるレベルであるかもしれませんね。
また、コンテナへの登録も13種類のクラスを登録しているだけですが、20[ms]前後かかっています。
これはアプリケーションの初期化時の遅延につながります。
大きなアプリケーションの場合、愚直にコンテナ登録をしてしまうと、体感へ悪影響がでてくるかもしれません?そんな大きなアプリあまりないかもしれませんが。
動作環境・開発状況比較
Container | Nuget Downloads | Latest Release | Latest Commited | PCL | .NET Standard | Prism |
---|---|---|---|---|---|---|
AutoFac | 3,441,183 | 2016/11/23 | 2017/1/3 | 〇 | 1.1 | 〇 |
DryIoc | 91,736 | 2017/1/12 | 2017/1/27 | △ | 1.0 | 〇 |
SimpleInjector | 811,212 | 2016/12/2 | 2016/11/27 | 〇 | 1.0 / 1.3 | - |
Unity | 4,900,116 | 2015/10/6 | 2016/5/18 | 〇 | - | 〇 |
DryIocは、「DryIoc」と「DryIoc.dll」の二つのDownload件数の合算値になっています。
無印側はNuGetを適用するとプロジェクト内部にコンテナのコードが追加されます。
それに対して、DryIoc.dllはアセンブリレベルでの参照になります。
なので無印はPCLのプロファイルや.NET Standardのバージョンなどに依存せず利用できる可能性が高いのですが、フレームワークから依存されていた場合は、DryIoc.dll側を参照する必要があります。
例えばPris,DryIoc.Formsとか。
最も.NET Standardの対応バージョンが1.0ですし、現時点でPCLのProfile259(UWPやWin8系も含めるやつ)でも動作しているので.dllを使って問題ないでしょう。
なお、StructureMapも本来は評価したかったのですが、StructureMap自体は.NET Standard 1.3向けに提供されているのに内部で.NET Standard1.6に依存しているため、今回は評価はあきらめました。。。
総括
とりあえず、Unityが不安なPrism.FormsユーザーはDryIocかAutoFacおすすめです。
実績自体はAutoFacの方が多いですがDryIocのパフォーマンスは魅力的ですね。
なお機能的な差異については詳細はまだ未調査ですが、最低限IoCコンテナとして求められる範囲はいずれも対応されています。
ちなみに今回のコードはこちらで公開しています。
私は最近のまともなスペックのAndroidやWin10mを持っていないので、お持ちの方はどなたか実験して記事を書いていただくか、面倒ならリリースビルドしてスクショを投げていただけるでもしていだけると嬉しいです。
という訳で今回はここまで。
それではまた!