0

私は IO についていくつかの調査を行っていましたが、バッファリング手法について説明している次の記事を読みました。基盤となるオペレーティング システムによるディスク アクセスと作業を最小限に抑えるために、バッファリング手法では、読み取り操作のたびにディスクから直接データを読み取るのではなく、チャンク単位でデータを読み取る一時バッファーを使用します。

バッファリングなしとありの例を示しました。

バッファリングなし:

try 
{ 
  File f = new File("Test.txt");
  FileInputStream fis = new FileInputStream(f);
  int b; int ctr = 0; 

  while((b = fis.read()) != -1) 
  { 
    if((char)b== '\t') 
    { 
      ctr++; 
    } 
  } 
  fs.close();
 // not the ideal way
 } catch(Exception e)
 {}

バッファリングあり:

try
{
  File f = new File("Test.txt");
  FileInputStream fis = new FileInputStream(f);
  BufferedInputStream bs = new BufferedInputStream(fis);
  int b;
  int ctr = 0;
  while((b =bs.read()) != -1)
  {
    if((char)b== '\t')
    {
      ctr++;
    }
  }
  fs.close(); // not the ideal way
}
catch(Exception e){}

結論は次のとおりです。

Test.txt was a 3.5MB  file 
Scenario 1 executed between 5200 to 5950 milliseconds for 10 test runs 
Scenario 2 executed between 40 to 62 milliseconds for 10 test runs.

Javaでこれを行うより良い方法は他にありますか? または、パフォーマンスを向上させる他の方法/テクニックはありますか?アドバイスしてください..!

4

3 に答える 3

1

Javaでこれを行うより良い方法は他にありますか? または、パフォーマンスを向上させるための他の方法/テクニックはありますか?

IO パフォーマンスに関しては、他の多くのコードがなければ、おそらくこれが最高になるでしょう。とにかくIOバウンドになる可能性が最も高いでしょう。

while((b =bs.read()) != -1)

これは、バイトごとに読み取るのは非常に非効率的です。テキスト ファイルを読んでいる場合は、BufferedReader代わりに a を使用する必要があります。これは、バイト配列を に変換しますString

BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
...
while ((String line = reader.readLine()) != null) {
   ...
}

また、どの IO でも必ず try/finally ブロックで実行して、確実に閉じる必要があります。

FileInputStream fis = new FileInputStream(f);
BufferedReader reader;
try {
    reader = new BufferedReader(new InputStreamReader(fis));
    // once we wrap the fis in a reader, we just close the reader
} finally {
    if (reader != null) {
       reader.close();
    }
    if (fis != null) {
       fis.close();
    }
}
于 2012-08-31T18:22:47.763 に答える
1

コードの問題は、ファイルをバイト単位で読み取っていることです (要求ごとに 1 バイト)。チャンクごとに配列チャンクに読み込むと、パフォーマンスはバッファと同じになります。

NIO とメモリ マップ ファイルも試してみてください。http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ314_029.htmを参照

于 2012-08-31T17:38:17.750 に答える
0

一度にデータのブロックを読み取ることができますが、バッファリングされた入力を使用するよりも高速です。

FileInputStream fis = new FileInputStream(new File("Test.txt"));
int len, ctr = 0;
byte[] bytes = new byte[8192];

while ((len = fis.read(bytes)) > 0)
    for (int i = 0; i < len; i++)
        if (bytes[len] == '\t')
            ctr++;
fis.close();

メモリ マッピングを試すこともできます。

FileChannel fc = new FileInputStream(new File("Test.txt")).getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
int ctr = 0;
for (int i = 0; i < bb.limit(); i++)
    if (bb.get(i) == '\t')
        ctr++;
fc.close();

これらのオプションは両方とも約 2 倍高速になると予想されます。

于 2012-08-31T19:13:37.543 に答える