Soma 0.11.0.0 リリース
F#で作ったO/Rマッパー Soma 0.11.0.0をリリースしました(F#はもちろんC#やVB.NETでも使えます)。ぜひお試しください。
Release Notes
- New Feature - SQLの解析結果のオブジェクトをキャッシュするようにしました。
- Change - FSharp.PowerPack.Linq.dll への依存を除去しました。
- Change - 式コメント中で使用できるファンクションの別名をいくつか追加しました。(C#で使いやすいように)
この中で一番インパクトがあるのは、2番目の「FSharp.PowerPack.Linq.dll への依存の除去」です。これまで、コードクォート式(コード引用符)の評価とSQLコメント内の式の評価にFSharp.PowerPack.Linq.dllを使っていたのですが、パフォーマンスが思ったよりでていなかったので、使うのをやめてリフレクションでがんばるように方針を変えました。これにより一部の処理のパフォーマンスがずいぶん良くなりました。Somaの元のつくりがいまいちだったということもあるのですが、特定の処理で計測すると1/10程度の速度で処理できるようになりました。
他のO/Rマッパーとの比較
Stack Overflowで使われているDapperというO/Rマッパーがあるのですが、このプロジェクトではいろんなO/Rマッパーで同等の処理をしてパフォーマンスを計測するプログラムを公開しています。これに Soma 0.11.0.0 を追加して実行してみました。
プログラムの内容は、主キーで1件SELECTしてオブジェクトにマッピングするということを500回繰り返してそれにかかる時間を計測するものです。
Somaは Find と Query の 2パターンを含めました。Findは主キーだけ指定、QueryはSQL全体を指定する処理です。
Find
somaDb.Find<Post>(id);
Query
somaDb.Query<Post>("select * from Posts where Id = /* id */0", new { id });
ベンチマークのプログラムがC#だったのでC#版のAPIで実行してます。
結果はこうなりました。500回分の時間を累計して速い順にソートされています。
O/R マッパー | 時間 |
---|---|
hand coded took | 149ms |
Mapper Query took | 151ms |
PetaPoco (Fast) took | 151ms |
PetaPoco (Normal) took | 154ms |
Dynamic Massive ORM Query took | 158ms |
Dynamic Mapper Query took | 160ms |
BLToolkit took | 187ms |
Linq 2 SQL Compiled took | 192ms |
Simple.Data took | 195ms |
SubSonic Coding Horror took | 218ms |
Entity framework CompiledQuery took | 229ms |
NHibernate SQL took | 242ms |
Soma : Find took | 278ms |
NHibernate HQL took | 285ms |
Linq 2 SQL ExecuteQuery took | 320ms |
Soma : Query took | 347ms |
Linq 2 SQL took | 850ms |
Entity framework ExecuteStoreQuery took | 920ms |
Entity framework ESQL took | 964ms |
Entity framework took | 1225ms |
Entity framework No Tracking took | 1245ms |
SubSonic ActiveRecord.SingleOrDefault took | 4785ms |
Somaの結果は真ん中よりちょっと後ろにあります。Find は hand coded(ADO.NET直)の2倍かからないくらい、Queryは hand coded の2.5倍かからないくらいの時間でした。他のO/Rマッパーと比べると相対的に真ん中より後ろになりますが、ページング用のSQLへの書き換えとかSQLコメント内の式評価とかの機能がある割には十分なパフォーマンスだと思います。でももうちょっとがんばれるかも。
それにしてもEntity FrameworkはCompiledQueryを除いてどれも遅いですね。まぁ、前バージョンのSomaのQueryはこれらよりさらに遅かったわけですが(^^;
ちなみに、ベンチマークの方法はごく単純なケースだけを計測していますし、比較対象の処理も完全に同等ともいえないので条件を変えればまた別の結果になりえます。あくまでも参考程度ということで。ベンチマークプログラムのオリジナルのソースコードは次のURLで公開されています。