2007年09月22日

ファイル読み出しコードの性能評価

C++でファイルの内容をメモリ上に読み出すコードを書いてみたところ、 書き方によって結構性能に差がありました。そこでちょっと性能を調べてみましたのでまとめておきます。

読み出しコード

C++では、メモリ上でのデータ保持方法は色々ありそうですが、 代表的なものということで、std::stringとstd::vectorに保持するコードを4つ選んでみました。

1つめのコード。Case1とします。

// Case1
using namespace std;
string Data(istreambuf_iterator<char>(ifstream(FileName, ios::in | ios::binary)),
  istreambuf_iterator<char>());
一行でも書ける短いコードです。

2つめのコード。Case2とします。

// Case2
using namespace std;
vector<char> Data(istreambuf_iterator<char>(ifstream(FileName, ios::in | ios::binary)),
  istreambuf_iterator<char>());
std::vectorを使ったこと以外はCase1と同じです。

3つ目のコード。Case3とします。

// Case3
using namespace std;
vector<char> Data;
copy(istreambuf_iterator<char>(ifstream(FileName, ios::in | ios::binary)),
  istreambuf_iterator<char>(), back_inserter(Data));
std::back_inserterを使ったC++らしいコードです。

最後のコード。Case4とします。

// Case4
using namespace std;
vector<char> Data;
std::ifstream Input(FileName, std::ios::in | std::ios::binary);
Data.resize(Input.seekg(0, std::ios::end).tellg());
Input.seekg(0, std::ios::beg).read(&Data[0], static_cast<std::streamsize>(Data.size()));
C言語に近い古い書き方。 シークしてファイルサイズを求めたら一気に読みだしています。

読み出しファイル

大きなファイルであれば何でも良いと思いましたので、 makedummyというツールを使って作った100MB(104,857,600 Bytes)のファイルを使いました。データはランダムです。

測定環境

測定環境は以下の通りです。

コンパイラVisual C++.NET 2003デフォルトコンパイラ
OSWindows XP Professional SP2
CPUAMD Athlon 64 3700+
メモリ2GB
HDDSeagate ST3300622AS
ファイルシステムNTFS
プロジェクト設定デフォルトRelease構成

測定結果

100MB位だとディスクキャッシュに格納されてしまうみたいなので、OS起動直後のファイルキャッシュに格納される前の読み出し時間を測るようにしました。 結果は以下の通り。
読出時間測定結果

時間を速度に変換してみました。1MB/s=1024×1024Byte/s です。
読出速度測定結果

分かったこと。

  • コンストラクタで読み出すCase1やCase2よりも、std::copyとback_inserterで読みだすCase3の方が速いです。
    コンストラクタでできることはコンストラクタでやるべきと思っていましたが、そうとも限らないようです。
  • それよりもさらにifstream::readで一気に読みだすCase4の方が速いです。なんと一番です。
    速度を重視するときはCase4が一番なのかもしれませんね。

投稿者 MASATO : 2007年09月22日 02:02 | トラックバック
コメント

とんでもなく遅レスで申し訳ありません。
stlのファイルロードで探しているうちにココにたどり着きました。
測定結果の差は、恐らくvectorの領域限界がくると
メモリの再確保→コピーを繰り返しているか否かだと思われます。
(内部実装的にvectorは2の階乗で領域を確保していたと思います。)
back_inserterの事はよく知りませんが、Case4に関しては
vector.resizeでその手間が省かれた分が速度に反映されたのでは、と思います。

貴重な情報ありがとうございました。

Posted by: 通りすがり : 2008年07月08日 17:19
コメントする









名前、アドレスを登録しますか?