前回はデータの書き込みのパフォーマンス測定を実施しました。今回はデータの読み込みのパフォーマンス測定を行いたいと思います。
Introduction
結果はともかく、測定の課程は散々でした。
InsertOne してもメモリが解放されないのもあれですが。
環境は前回と同じです。
Explanation
Read Small Objects
まず、下記のオブジェクトを1,000,000個書き込みます。
データベースは、SmallObjectData、コレクション名は、SmallObjectData です。
1 | public sealed class SmallObjectData |
No プロパティには 0 から 999,999 が入ります。
そのあと、No プロパティを 100000 で剰余した余りが0のものだけを Select します。
下記のようなコードになります。
1 | var collection = database.GetCollection<SmallObjectData>(CollectionName); |
ToList メソッドをコールしているのは、この時点で検索結果を確定して、オブジェクトを取得するためです。
IEnumerable の場合、実際に使用するまでは、評価はされないので。
試行回数は3回で、平均値をとっています。
が、どうも最初だけ遅くて、あとはキャッシュが効いている感じがします。
なので、10回の試行で平均値をとります。
平均は420.8 ms でした。
Read Large Objects
まず、下記のオブジェクトを1,000,000個書き込みます。
データベースは、LargeObjectData、コレクション名は、LargeObjectData です。
1 | public sealed class LargeObjectData |
No プロパティには 0 から 999,999 が入ります。
そのあと、No プロパティを 100000 で剰余した余りが0のものだけを Select します。
Select コードは前段と同じです。
が、結論から言うと、計測できませんでした。
剰余する数を増やそうが減らそうがとにかく、mongod.exe が OutOfMemoryException でこけます。
Selectする段階で、途中結果を解放していないのかしりませんが、メモリが急激に増えていって、こけます。
例外は、
1 | ハンドルされていない例外: System.FormatException: An error occurred while deserializing the DataBytes property of class MongoDB7.Program+MiddleObjectData: 種類 'System.OutOfMemoryException' の例外がスローされました。 ---> System.OutOfMemoryException: 種類 'System.OutOfMemoryException' の例外がスローされました。 |
とでます。
ReadBytes とあるので、mongod.exe からの結果の受け渡しか何かのためのバッファを作成するために、マネージドにメモリを作った際、LOHがたくさんあって、メモリが確保できずに例外発生、というように見えます。
Read Middle Objects
とにかくオブジェクトサイズを減らしてみます。
GC が苦手とする 85,000 が問題としか思えませんので、オブジェクト全体が 85,000 バイトを超えないようにします。
前段のオブジェクト同じですが、DataBytes の長さを 80,000 にします。
1 | public sealed class MiddleObjectData |
これを1,000,000 個追加すると、下記の結果になりました。
1 | Data Size 80.1 gb |
これで一つのオブジェクトの復元で 85,000 バイトを超えないので、 LOH にならず、GC の影響を避けることができます。
これでこれまでと同じようにselectしてみます。
今度は成功しました。が、べらぼうに遅いです。
でも、オブジェクトサイズによって、何かしら致命的な影響があるように見えます。
Conclusion
3種のオブジェクトを検索した結果は下記になります。
オブジェクトサイズ/オブジェクト数 | 1,000,000 |
---|---|
Small ( 51.0 bytes) | 420.8 ms |
Middle (80.1 kb) | 221577.1 ms |
Large (100 kb) | 計測不可 |
.NETのGCの影響をもろに受けているとしか思えない感じです。
次回はインデックスを使って、検索速度の改善を試みたいと思います。
Source Code
テストに使った最終的なコードは下記になります。
https://github.com/takuya-takeuchi/Demo/tree/master/Database/MongoDB/MongoDB7