たとえば、空白で区切られた ASCII テキストとして格納された約 1.5 Gb 相当の浮動小数点数を含むデータ ファイルがあります1.2334 2.3456 3.4567
。
このような数値を処理する前に、まず元のファイルをバイナリ形式に変換します。float
これは、またはを使用するかどうかを選択しdouble
、ファイル サイズを ( の場合は約 800 MB にdouble
、 の場合は 400 MB にfloat
) 削減し、データの処理中に適切なサイズのチャンクで読み取ることができるため、便利です。
ASCII からバイナリへの変換を行うために、次の関数を作成しました。
template<typename RealType=float>
void ascii_to_binary(const std::string& fsrc, const std::string& fdst){
RealType value;
std::fstream src(fsrc.c_str(), std::fstream::in | std::fstream::binary);
std::fstream dst(fdst.c_str(), std::fstream::out | std::fstream::binary);
while(src >> value){
dst.write((char*)&value, sizeof(RealType));
}
// RAII closes both files
}
を高速化したいのacii_to_binary
ですが、何も思いつかないようです。ファイルを 8192 バイト単位で読み取ってから、別のサブルーチンでバッファを処理しようとしました。これは非常に複雑に思えます。なぜなら、バッファ内の最後の数文字が空白 (この場合はすべて良い) であるか、切り捨てられた数値 (非常に悪い) である可能性があるからです。
この関数を高速化するにはどうしますか? ブーストなどの依存関係を追加せずに、標準の C++ (C++11 で問題ありません) に依存したいと思います。
ありがとうございました。
編集:
@DavidSchwarts:
私は次のようにあなたの提案を実装しようとしました:
template<typename RealType=float>
void ascii_to_binary(const std::string& fsrc, const std::string& fdst{
std::vector<RealType> buffer;
typedef typename std::vector<RealType>::iterator VectorIterator;
buffer.reserve(65536);
std::fstream src(fsrc, std::fstream::in | std::fstream::binary);
std::fstream dst(fdst, std::fstream::out | std::fstream::binary);
while(true){
size_t k = 0;
while(k<65536 && src >> buffer[k]) k++;
dst.write((char*)&buffer[0], buffer.size());
if(k<65536){
break;
}
}
}
しかし、データを書き込んでいないようです!私はそれに取り組んでいます...