したがって、数値データの「非常に大きな」ASCII ファイル (合計でギガバイト) が「多数」あり、プログラムはその全体を少なくとも 1 回は順番に処理する必要があります。
データの保存/読み込みに関するアドバイスはありますか? ファイルをバイナリに変換して、ファイルを小さくし、読み込みを高速化することを考えました。
一度にすべてをメモリにロードする必要がありますか?
そうでない場合、データを部分的にロードする良い方法は何ですか?
Java 関連の効率化のヒントは何ですか?
したがって、数値データの「非常に大きな」ASCII ファイル (合計でギガバイト) が「多数」あり、プログラムはその全体を少なくとも 1 回は順番に処理する必要があります。
データの保存/読み込みに関するアドバイスはありますか? ファイルをバイナリに変換して、ファイルを小さくし、読み込みを高速化することを考えました。
一度にすべてをメモリにロードする必要がありますか?
そうでない場合、データを部分的にロードする良い方法は何ですか?
Java 関連の効率化のヒントは何ですか?
では、処理で複数のファイルと複数のバッファのデータをジャンプする必要がある場合はどうなるでしょうか? バイナリ ファイルを頻繁に開いたり閉じたりするとコストが高くなりますか?
私は「メモリ マップド i/o」、別名「ダイレクト バイト バッファ」の大ファンです。Java では、 Mapped Byte Buffersと呼ばれ 、java.nio の一部です。(基本的に、このメカニズムは OS の仮想メモリ ページング システムを使用してファイルを「マップ」し、それらをプログラムでバイト バッファーとして表示します。OS は、ディスクおよびメモリとの間のバイトの移動を自動的に魔法のように非常に迅速に管理します。
このアプローチをお勧めする理由は、a) 私にとってはうまくいき、b) アルゴリズムに集中でき、JVM、OS、およびハードウェアにパフォーマンスの最適化を任せることができるからです。多くの場合、彼らは私たち下級プログラマーよりも何が最善かを知っています。;)
あなたのコンテキストで MBB をどのように使用しますか? ファイルごとに MBB を作成し、必要に応じて読み取るだけです。結果を保存するだけで済みます。.
ところで: GB 単位でどのくらいのデータを扱っていますか? 3 ~ 4 GB を超える場合、これは 32 ビット マシンでは機能しません。これは、MBB 実装がプラットフォーム アーキテクチャによってアドレス指定可能なメモリ空間に対して防御されているためです。64 ビットのマシンと OS では、1 TB または 128 TB のマッピング可能なデータを使用できます。
パフォーマンスについて考えているなら、Kirk Pepperdine (やや有名な Java パフォーマンスの第一人者) を知っているでしょう。彼は Web サイト (www.JavaPerformanceTuning.com) に関与しており、MBB の詳細 ( NIO Performance Tipsやその他の Java パフォーマンス関連) を掲載しています。
Wide Finder Projectのエントリを参照してください( 「wide finder」 javaを Google 検索してください)。
ワイド ファインダーでは、ログ ファイルの多くの行を読み取る必要があるため、Java の実装を調べて、何が機能し、何が機能しなかったかを確認してください。
これは、ファイル内のデータに大きく依存します。大規模なメインフレームは長い間シーケンシャル データ処理を行ってきましたが、通常はデータにランダム アクセスを使用しません。彼らは一度に一列に並べて、それを処理してから続行します。
ランダム アクセスの場合、構築する必要があるデータがファイル内のどこにあるかを認識しているキャッシング ラッパーを使用してオブジェクトを構築するのが最善の場合がよくあります。必要に応じて、そのデータを読み取り、自分自身を構築します。このようにして、メモリが不足しているときに、後で取り戻せないことをあまり心配することなく、ものを殺し始めることができます.
バイナリに変換できますが、元のデータを保持する必要がある場合は、データのコピーが 1 つ以上あります。
元の ascii データの上にある種のインデックスを構築することが実用的である場合があります。これにより、データを再度調べる必要がある場合に、後でより迅速に処理できるようになります。
質問に順番に答えるには:
一度にすべてをメモリにロードする必要がありますか?
する必要がない場合はありません。一部のファイルではできる場合がありますが、順次処理するだけの場合は、何らかの種類のバッファリングされた読み取りを 1 つずつ実行し、途中で必要なものをすべて保存します。
そうでない場合、データを部分的にロードする良い方法は何ですか?
BufferedReaders/etc は最も単純ですが、FileChannel/etc を詳しく調べて、メモリマップ I/O を使用して一度にデータのウィンドウを通過することもできます。
Java 関連の効率化のヒントは何ですか?
それは、データ自体で何をしているかに大きく依存します!
どのような処理が行われているのかについての追加の洞察はありませんが、同様の作業を行ったときの一般的な考えを以下に示します。
データセットに対して任意の操作を実行するアプリケーションのプロトタイプ (おそらく「捨てるもの」) を作成します。それがどれくらい速くなるか見てください。あなたが考えることができる最も単純で最も素朴なことが許容できるほど速いのであれば、心配する必要はありません!
単純なアプローチが機能しない場合は、データを前処理して、後続の実行が許容できる時間内に実行されるようにすることを検討してください。あなたは、データセットをかなり「飛び回る」必要があると述べています。それを前処理する方法はありますか?または、1 つの前処理ステップとして、データ セットの重要で必要なセクションに関するバイト単位の正確な位置情報を提供する、さらに多くのデータ (インデックス データ) を生成することもできます。次に、メイン処理の実行でこの情報を利用して、必要なデータに直接ジャンプできます。
要約すると、私のアプローチは、今すぐ簡単なことを試して、パフォーマンスがどのように見えるかを確認することです. 多分それはうまくいくでしょう。それ以外の場合は、データを複数のステップで処理することを検討し、最もコストのかかる操作を頻度の低い前処理のために節約します。
「すべてをメモリにロード」しないでください。ファイル アクセスを実行するだけで、オペレーティング システムのディスク ページ キャッシュが、実際にメモリから直接データを引き出すタイミングを決定します。
あなたは本当にあなたを助けるのに十分な情報を私たちに提供していません. 処理するために、各ファイルを完全にロードする必要がありますか? それとも行ごとに処理できますか?
一度にファイル全体をロードすると、それほど大きくないファイルでもパフォーマンスが低下する可能性があります。あなたの最善の策は、あなたに合ったバッファサイズを定義し、一度にバッファのデータを読み込んで処理することです。
可能であれば、データをデータベースに取得します。次に、そこで利用可能なすべてのインデックス作成、キャッシュ、メモリ固定、およびその他の機能を活用できます。
データに複数回アクセスする必要がある場合は、データベースにロードします。ほとんどのデータベースには、何らかのバルク ロード ユーティリティがあります。データがすべてメモリに収まり、頻繁にデータを保持したりアクセスしたりする必要がない場合は、おそらく Perl またはお気に入りのスクリプト言語で簡単なものを作成できます。
Informatica は非常に便利なデータ処理ツールであることがわかりました。幸いなことに、最近のバージョンでは Java 変換も許可されています。テラバイト単位のデータを扱っている場合は、最高の ETL ツールを利用する時期かもしれません。
ここでの処理の結果をどこかに保存するなど、何かをしたいと思っていると思います。
数値データが定期的にサンプリングされ、ランダム アクセスを行う必要がある場合は、それらをquadtreeに格納することを検討してください。
入力を高速化するために、正規表現を強く活用し、「新しい」IO nio パッケージを調べることをお勧めします。その後、ギガバイト単位のデータが移動することを現実的に期待できる限り迅速に移動する必要があります。