2011-12-07 14 views
1

私はこのような独立したブロックからなる適度に大きなバイナリファイルを有する:ブロック数、各ブロックのサイズとファイルの合計サイズが非常A変動高性能読み取り - リナックス/ pthreadの

 
header1 
data1 
header2 
data2 
header3 
data3 
... 

をロットですが、典​​型的な数値は〜1000ブロック、平均ブロックサイズは100kbです。ファイルは、私が制御できない外部アプリケーションによって生成されますが、できるだけ早くそれらを読みたいと思っています。多くの場合、ブロックのほんの一部(10%)にしか興味がありませんが、これは私が最適化する場合です。

私の現在の実装は次のようである:

  1. ファイルを開き、すべてのヘッダー読み取り - 次のヘッダの場所に(FSEEKするヘッダ内の情報を使用して)。開いているFILE *ポインタを保持します。
  2. データが要求されると、fseek()を使用してデータブロックを検索し、すべてのデータを読み取り、それを返します。

これはうまくいきますが、私はおそらく(?)考えていました。私は聞いたことがある。

どのような考えですか?

Joakim

答えて

1

ほとんどの場合、おそらくディスクへのアクセスに費やされます。おそらくSSDを買うのは分かりやすいでしょう。 (あなたが何をしていても、あなたのアプリケーションはI/Oに縛られています)。

あなたのファイルは約100Mbです。ディスク(カーネルファイル)のキャッシュに読み込むだけでそれを得ることができます。プログラムを実行する前にcat yourfile > /dev/nullと入力してください。このような小さなファイル(RAMに収まる妥当なマシン上)では、それほど心配する必要はありません。

テキストファイルを前処理することができます。データベース(sqlite、またはPostGreSQLのような実際のRDBMS用)を作成するか、またはgdbmインデックスファイルを作成します。

mがそれを-ing mmapを依頼するGNU glibcの拡張である)あなたがsetbufferでより大きなバッファを持っている、または"rmt"モードでfopenを呼ぶかもしれない<stdio.h>を使用している場合。

mmapmadviseを使用できます。

readahead(おそらく別のスレッドで)システムコールを使用できます。

しかし、あなたのファイルはそれほど気にならないほど小さく見えます。本当にパフォーマンス上の問題だと思いますか? 1日に何千回もファイルを読んでいるのですか、何百ものファイルがありますか?

+0

ありがとうございます - 私はmmap + madviseと私が気づいていなかったreadaheadシステムコールを調べます。しかし、あなたは正しいです - おそらくパフォーマンスは十分です。 – user422005

+0

まずは 'cat'トリックを試してみてください...あなたは驚かれるでしょう...しかし、本当にあなたはあまりにも心配していると思います... –

2

mmapとreadの速度の差はそれほど大きくなく(両方ともディスクからデータを読み取る必要があります)、mmapの最大の利点はダブルバッファリングを避けることです。

コンテンツの10%にしか興味がない場合、最大の節約はでなく、になり、残りの90%を読んでください。これはヘッダーを読み込み、次のヘッダーまたはデータブロックが必要になった場合にのみ実行できます。しかし、それはすべて、OPが詳細に示さなかったファイル形式に依存します。

関連する問題