0

したがって、1行に1つのコンマ区切りのレコードで埋められたこれらの巨大なテキストファイルがあります。特定の条件を満たす行を削除して、ファイルを1行ずつ処理する方法が必要です。フィールドの1つが特定の長さより短いなど、一部の削除は簡単です。最も難しい基準は、これらの行にすべてタイムスタンプがあることです。多くのレコードはタイムスタンプを除いて同一であり、同一で互いに15秒以内のレコードを除くすべてのレコードを削除する必要があります。

ですから、他の人がこれに対する最善のアプローチを考え出すことができるかどうか疑問に思います。私は、タイムスタンプにJodaTimeを使用して、タスクを実行するJavaの小さなプログラムを思いつきました。これにより、非常に簡単になります。ただし、プログラムを最初にコーディングした方法では、OutofMemoryヒープスペースエラーが発生していました。コードを少しリファクタリングしましたが、ほとんどの場合は問題ないように見えましたが、プログラムがハングアップしているように見えることがあるため、メモリの問題があると思います。それとそれはあまりにも時間がかかるようです。これがメモリリークの問題なのか、コーディングの問題なのか、それともまったく別の問題なのかはわかりません。はい、ヒープサイズを大幅に増やしてみましたが、それでも問題が発生していました。

プログラムはPerlかJavaのどちらかである必要があると言います。Pythonスクリプトも機能させることができるかもしれませんが、Pythonについてはあまり詳しくありません。私が言ったように、タイムスタンプはJodaTimeライブラリのおかげで(私にとって)Javaで最も簡単です。Perlでタイムスタンプをどのように実行するかわかりません。しかし、私は、最も効果的なものを学び、使用する準備ができています。

また、読み込まれるファイルのサイズは大きく異なりますが、大きなファイルの中には約100Mbで、130万レコードのようなものもあります。

私のコードは基本的にすべてのレコードを読み取り、それらをハッシュマップに配置します。キーは、同様のレコードが共有するレコードのデータの特定のサブセットです。したがって、異なるタイムスタンプを含まないレコードのサブセット。このようにすると、同じデータを持ついくつかのレコードが作成されますが、それは異なる時間に発生します。(タイムスタンプを除いて完全に同一です)。

したがって、各キーの値は、データの同じサブセットを持つすべてのレコードのセットです。次に、ハッシュマップを繰り返し処理し、各セットを取得して繰り返し処理します。最初のレコードを取得し、その時間を他のすべてのレコードと比較して、15秒以内かどうかを確認します。その場合、レコードは削除されます。そのセットが完了すると、すべてのレコードが完了するまでファイルに書き出されます。うまくいけば、それは理にかなっています。

これは機能しますが、明らかに私が行っている方法はメモリを大量に消費します。誰かがそれを行うためのより良い方法について何かアイデアがありますか?または、Javaプログラムを現在の実装に挿入しようとすると、他にも多くの問題が発生するため、Perlでこれを実行できる方法は実際には良いでしょう。おそらくそれは私のメモリの問題と貧弱なコーディングのせいですが。

最後に、私は誰かに私のためにプログラムを書くように頼んでいません。擬似コードは問題ありません。あなたがPerlのアイデアを持っているなら、私はもっと詳細を使うことができます。Perlで行う方法がわからない主なことは、時間比較です。私はPerlライブラリを少し調べましたが、JodaTimeのようなものは見ていません(あまり調べていませんが)。任意の考えや提案をいただければ幸いです。ありがとうございました。

4

2 に答える 2

4

ロット全体をメモリに格納する必要があるため、すべての行を読み取ることは理想的ではありません。

代わりに、1行ずつ読み取り、保持したいレコードを書き出すことができます。以前にヒットした行のキャッシュを保持して、現在のプログラムから15秒以内に制限することができます。非常に大まかな擬似コードでは、読むすべての行について次のようになります。

var line = ReadLine()
DiscardAnythingInCacheOlderThan(line.Date().Minus(15 seconds);
if (!cache.ContainsSomethingMatchingCriteria()) {
   // it's a line we want to keep
   WriteLine(line);
}

UpdateCache(line);  // make sure we store this line so we don't write it out again.

指摘したように、これは行がタイムスタンプ順になっていることを前提としています。そうでない場合は、UNIXsortを使用して作成します。これは、非常に大きなファイルを非常に楽しく処理できるためです。

于 2013-01-11T15:42:05.477 に答える
0

ファイルを読み取り、削除する行番号だけを出力する場合があります(並べ替えて別のパスで使用します)。ハッシュマップには、必要な最小限のデータと行番号だけを含めることができます。必要なデータが行サイズに比べて小さい場合、これにより多くのメモリを節約できます。

于 2013-01-11T15:56:21.727 に答える