ファイルからの読み取りパフォーマンスを向上させるために、大きな(数MBの)ファイルのコンテンツ全体をメモリに読み取り、istringstreamを使用して情報にアクセスしようとしています。
私の質問は、この情報を読み取り、文字列ストリームに「インポート」する最良の方法です。このアプローチの問題(以下を参照)は、文字列ストリームを作成するときにバッファーがコピーされ、メモリ使用量が2倍になることです。
#include <fstream>
#include <sstream>
using namespace std;
int main() {
ifstream is;
is.open (sFilename.c_str(), ios::binary );
// get length of file:
is.seekg (0, std::ios::end);
long length = is.tellg();
is.seekg (0, std::ios::beg);
// allocate memory:
char *buffer = new char [length];
// read data as a block:
is.read (buffer,length);
// create string stream of memory contents
// NOTE: this ends up copying the buffer!!!
istringstream iss( string( buffer ) );
// delete temporary buffer
delete [] buffer;
// close filestream
is.close();
/* ==================================
* Use iss to access data
*/
}
_std::ifstream
_には、filebuf
へのポインターを返すメソッドrdbuf()
があります。次に、このfilebuf
をstringstream
に「プッシュ」できます。
_#include <fstream>
#include <sstream>
int main()
{
std::ifstream file( "myFile" );
if ( file )
{
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
// operations on the buffer...
}
}
_
編集:Martin Yorkがコメントで述べているように、stringstream
の_operator<<
_はfilebufを1文字ずつ読み取るため、これは最速のソリューションではないかもしれません。あなたは彼の答えを確認したいと思うかもしれません。彼はあなたがしたようにifstream
のread
メソッドを使用し、以前に割り当てられたメモリを指すようにstringstream
バッファを設定します。
OK。ファイルから読み取るよりも速くなるとは言いません
しかし、これは一度バッファを作成し、データがバッファに読み込まれた後、それを文字列ストリームのソースとして直接使用する方法です。
N.B.Std :: ifstreamがバッファリングされていることに言及する価値があります。 (比較的大きな)チャンクでファイルからデータを読み取ります。ストリーム操作はバッファに対して実行され、さらにデータが必要なときに別の読み取りのためにファイルに戻ります。したがって、すべてのデータをメモリに取り込む前に、これがボトルネックであることを確認してください。
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
std::ifstream file("Plop");
if (file)
{
/*
* Get the size of the file
*/
file.seekg(0,std::ios::end);
std::streampos length = file.tellg();
file.seekg(0,std::ios::beg);
/*
* Use a vector as the buffer.
* It is exception safe and will be tidied up correctly.
* This constructor creates a buffer of the correct length.
*
* Then read the whole file into the buffer.
*/
std::vector<char> buffer(length);
file.read(&buffer[0],length);
/*
* Create your string stream.
* Get the stringbuffer from the stream and set the vector as it source.
*/
std::stringstream localStream;
localStream.rdbuf()->pubsetbuf(&buffer[0],length);
/*
* Note the buffer is NOT copied, if it goes out of scope
* the stream will be reading from released memory.
*/
}
}
これは私にとって時期尚早な最適化のようです。処理で行われている作業の量。組み込みシステムではなく、近代的なデスクトップ/サーバーを想定すると、初期化中に数MBのデータをコピーすることは、特にそもそもディスクからファイルを読み取ることに比べて、かなり安価です。私はあなたが持っているものに固執し、それが完了したときにシステムを測定し、潜在的なパフォーマンスの向上が価値があるかどうかを決定します。もちろん、メモリが不足している場合、これは内部ループ、または頻繁に呼び出される(1秒間に1回など)プログラムであり、バランスを変更します。
留意すべきもう1つのことは、ファイルI/Oが常に最も遅い操作になることです。 Luc Tourailleのソリューションは正しいですが、他のオプションもあります。ファイル全体を一度にメモリに読み込むことは、個別の読み込みよりもはるかに高速です。