私は効率を非常に気にする何かに取り組んでいます。何千ものファイルがあり、各ファイルは 300M にもなります。各ファイルには、少なくとも 50 万個のアイテムが含まれています。私の仕事は、各アイテムをできるだけ迅速に処理することです。物理メモリ サイズは問題ではありません。そう。ディスクから各項目を取得する代わりに、ファイル全体をメモリにコピーしてメモリから各項目を取得することでメリットがありますか? また、IO プロセスの時間を節約できる他の方法はありますか? ありがとうございました!
2 に答える
mmap (2) 、 madvise(2 )、posix_fadvise(2)、およびreadahead(2 ) syscallを使用できます(これは Linux 固有でブロックされていることに注意してreadahead
ください。事前に、または別のスレッドで呼び出したい場合があります)。
あまり気にしないかもしれませんが、200Mb の各ファイルを処理する数秒前に事前に読み取るだけで十分な場合があります。カーネル ファイル システムとディスク キャッシュは多くのことを行っています。大量の RAM データが既にメモリ内にある場合。
そして、あなたのプログラムが単一の長時間持続するプロセスなのか、それとも大きなファイルごとに同じプログラムを呼び出す繰り返しスクリプトを介して実行するのかについては教えてくれませんでした.
システム構成とハードウェアは非常に重要です。mke2fs
大きなブロック (16Kb または 64Kb など) を使用してファイル システムを構成できます (その時点で)。それらを買う余裕があれば、SSD ディスクは多くのものをもたらすでしょう。
巧妙にセットアップされたデータベースを慎重に使用するようにアプリケーションを設計することもできます。
手始めに:
std::vector<char> input;
std::ifstream file("filename.txt")'
// maybe find file size and do a reserve on input
std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>()
std::back_inserter(input));
これが実際に十分に高速ではない場合、通常、メモリ マップ ファイルは多くの IO オーバーヘッドを削減します。
Boost.Iostreamライブラリは、移植可能なメモリ マップ ファイルを最新のインターフェイスで提供し、非常に高速です。
とにかく、最初に簡単な解決策を試して、ファイル IO プロセスをパーサーと実際の処理から分離するようにプログラムを構成してから、実際にコストがかかる部分を最適化します。このようなプログラム構造により、プロデューサー/コンシューマーの並列処理も簡単に実装できます。
あなたが何であるかも重要な部分ですitems
。に直接マッピングできますか、struct
それとも処理する必要がありますか。もしそうなら、実際の解析はどのくらい複雑ですか?