前回は脇道にそれてパスワードの設定を実施しました。今回はデータの書き込みのパフォーマンス測定を行いたいと思います。

Introduction

NpSQLの売りはデータの読み書きです。RDBMSが持つ柔軟な集計や検索をある程度犠牲にして得た特徴ですが、どの程度凄いのでしょうか。
大量のデータの読み書きのパフォーマンスを計測してみます。
環境は

1
2
3
4
OS:Windows 10 Pro 64bit
CPU:Intel Core i3-4130 3.40GHz
メモリ:16GB
HDD:WesternDigital WD10EACS-22D6B0

Explanation

Write Small Objects

下記のオブジェクトを1,000,000個書き込みます。
試行回数は3回で、平均値をとっています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public sealed class Data
{

public ObjectId Id
{
get;
set;
}

public int No
{
set;
get;
}

public DateTime Established
{
get;
set;
}

}

MongoDB上では、書き込みの結果、下記の数値が得られました。

1
2
3
4
Data Size 51.0 mb
Storage Size 14.4 mb
Avg Obj Size # 51.0 bytes
Objects # 1000000
オペレーション/オブジェクト数 1,000,000
Drop 228.5 ms
Insert (One) 132881.25 ms
Insert (Many) 131191.67 ms
Select (Countだけ) 11 ms

OneとManyは、Insertに使うメソッドの違いです。単一のオブジェクトの挿入かIEnumrableの挿入かの違いです。
差はないも同然でしたが。
一応書き込みは0.1-0.2ms/個のようです。これは速いのか?

Write Large Objects

次は下記のオブジェクトを1,000,000個書き込みます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public sealed class LargeData
{

public ObjectId Id
{
get;
set;
}

public byte[] DataBytes
{
set;
get;
}

public DateTime Established
{
get;
set;
}

}

試行回数は3回で、平均値をとっています。
byte[]のサイズは100,000です。少なくともGCが苦手とする85,000よりは大きくしました。

ですが、残念なことに、書き込み終わる前に OutOfMemoryException でサンプルプログラムが落ちました。
落ちた直後のデータベースは

1
2
3
4
Data Size 100 gb
Storage Size 8.22 gb
Avg Obj Size # 100 kb
Objects # 1000000

となっていました。
(まぁこれは、InsertOneによる結果ですが)

TaskManager

恐ろしいマネージャー。

Storage

恐ろしいストレージ。

計測できないので、1桁落として、100,000個にします。
あと、データベースを一度全てリセットします。

が、これも落ちる。ちなみに落ちるのは、InsertMany メソッド。
ちょっとあれなので計算しました。

100,000(個)*100(kb)=9765MB

とすると、半分ならギリギリ大丈夫?
…ダメでした。25,000でようやくOKでしたが、それでもメモリは5GB近く確保したままでした。
でも、InsertOneなら1,000,000個挿入しても、7GBまで保持しました。なんで?

このテスト、すっごいHDDに負荷かかる(白目) ずっとHDD、100%なんだぜ?

オペレーション/オブジェクト数 25,000 1,000,000
Drop 235 ms 246.3 ms
Insert (One) 16815 ms 818100 ms
Insert (Many) 19671 ms 計測不可
Select (Countだけ) 14.67 ms 計測不可

参考値ですが、オブジェクト数とスピードは比例に近い感じですね。
あと、0.81ms/個のようです。こちらは単純にオブジェクトサイズには比例しないようですが。

Conclusion

予想以上に苦労しました。
まさかOutOfMemoryExpcetionで躓くとは予想外でした。
パフォーマンスとしては、あまり良いとも悪いとも言えないです。
どこかでRDMBSで似たデータ構造の比較試験がないでしょうか?

次は読み込みのパフォーマンス試験を予定です。

Source Code

テストに使った最終的なコードは下記になります。
https://github.com/takuya-takeuchi/Demo/tree/master/MongoDB5