あなたが得たFIRとSMAの回答はあなたの場合には良いですが、より一般的なアプローチを推し進める機会を得たいと思います。
ここにあるのはデータのストリームです:一度にすべてのデータをメモリに読み込む必要がある3つの大きなステップ(データの取得、計算、出力結果)でプログラムを構造化する代わりに、パイプラインとして構造化できます。
パイプラインは、ストリームで始まり、それを変換し、シンクにプッシュします。
あなたの場合、パイプラインは次のようになります。
- ディスクからアイテムを読み取り、一度に1つずつアイテムを発行します
- アイテムを1つずつ受信します。受信した各アイテムについて、最後に受信した5つを送信します(循環バッファーが入る場所)
- グループごとに結果を計算し、一度に5個のアイテムを受け取ります
- 結果を受け取り、ディスクに書き込みます
C ++は、ストリームではなくイテレータを使用する傾向がありますが、正直なところ、ストリームのモデル化は簡単です(ストリームに似た範囲の提案があります)。
template <typename T>
class Stream {
public:
virtual boost::optional<T> next() = 0;
virtual ~Stream() {}
};
class ReaderStream: public Stream<Item> {
public:
boost::optional<Item> next() override final;
private:
std::ifstream file;
};
class WindowStream: public Stream<Window> {
public:
boost::optional<Window> next() override final;
private:
Window window;
Stream<Item>& items;
};
class ResultStream: public Stream<Result> {
public:
boost::optional<Result> next() override final;
private:
Stream<Window>& windows;
};
そして、パイプラインは次のようになります。
ReaderStream itemStream("input.txt");
WindowStream windowStream(itemsStream, 5);
ResultStream resultStream(windowStream);
std::ofstream results("output.txt", std::ios::binary);
while (boost::optional<Result> result = resultStream.next()) {
results << *result << "\n";
}
ストリームは常に適用できるとは限りません(データへのランダムアクセスが必要な場合は動作しません)が、ストリームは揺らぎます:非常に少量のメモリを操作することにより、すべてをCPUキャッシュに保持します。
別のメモ:あなたの問題は「恥ずかしいほど平行」であるように思えます、あなたは大きなファイルをチャンクに分割したいかもしれませんそして、チャンクを並行して処理します。
CPUが(I / Oではなく)ボトルネックの場合、ファイルをほぼ同じ量に分割した後、コアごとに1つのプロセスを起動することで、CPUを高速化できます。
V新しい配列ではなくステップを保存することもできます。基本的には、あなたの問題はあなたのアルゴリズムまたはデータ構造のいずれかにあると思います。詳細が分からないので、それを効率的に行う方法を知るのは難しいです。