web-dev-qa-db-ja.com

BufferedInputStreamの使用

この投稿の前に、注意を1つ付けておきます。私はJavaに関してはまったくの初心者です。私はしばらくの間PHPのオンとオフをプログラミングしてきましたが、デスクトップアプリケーションを作成する準備ができていたので、さまざまな理由でJavaを使用することにしました。 。

私が取り組んでいるアプリケーションは初期段階(5クラス未満)であり、ローカルファイルからバイトを読み取る必要があります。通常、ファイルは現在512kB未満です(ただし、将来的に大きくなる可能性があります)。現在、私はFileInputStreamを使用してファイルを3バイト配列に読み込みます。これは、私の要件を完全に満たしています。しかし、私はBufferedInputStreamについて言及しているのを見て、現在これを行っている方法が最善かどうか、またはBufferedInputStreamも使用する必要があるかどうか疑問に思いました。

Stack Overflowでいくつかの調査を行い、いくつかの質問を読みましたが、BufferedInputStreamを使用する場合と使用しない場合の最適な状況を理解するのにまだ問題があります。私の状況では、バイトを読み取った最初の配列はほんの数バイト(20未満)です。受信したデータがこれらのバイトで適切である場合、ファイルの残りの部分をさまざまなサイズのさらに2つのバイト配列に読み込みます。

また、多くの人がプロファイリングについて言及し、それぞれの特定のケースでどちらがより効率的かを確認していると聞きましたが、プロファイリングの経験がなく、どこから始めればよいのかよくわかりません。これについてもいくつか提案をお願いします。

長い投稿で申し訳ありませんが、これらのことを行うための最良の方法を学び、理解したいと思います。私はいつも自分の決定を二度と推測するという悪い習慣を持っているので、フィードバックが欲しいです。ありがとう!

35
Jason Watkins

小さな読み取りを一貫して行っている場合は、BufferedInputStreamを使用するとパフォーマンスが大幅に向上します。バッファリングされていないストリームに対する各読み取り要求は、通常、要求されたバイト数を読み取るためにオペレーティングシステムへのシステムコールをもたらします。システムコールを実行するオーバーヘッドは、syscallごとに数千のマシン命令になる可能性があります。バッファリングされたストリームは、(たとえば)最大8kバイトの1回の大きな読み取りを内部バッファに実行し、そのバッファからバイトを渡すことによってこれを減らします。これにより、システムコールの数を大幅に減らすことができます。

ただし、常に大規模な読み取り(8k以上など)を実行している場合は、BufferedInputStreamによって処理速度が低下します。通常、システムコールの数を減らすことはなく、バッファリングによって追加のデータコピー手順が発生します。

あなたのユースケース(最初に20バイトのチャンクを読み取り、次に大きなチャンクをたくさん読み取る)では、BufferedInputStreamを使用すると、パフォーマンスを向上させるよりも低下させる可能性が高いと言えます。しかし、最終的には、実際の読み取りパターンに依存します。

81
Stephen C

比較的大きな配列を使用して一度にチャンクでデータを読み取る場合、BufferedInputStreamは無駄なコピーを導入するだけです。 (readは必ずしもすべての配列を読み取るとは限りません。DataInputStream.readFullyが必要な場合があります)。 BufferedInputStreamが勝つのは、小さな読み取りをたくさん行うときです。

BufferedInputStreamは、事前に必要なファイルをさらに読み取ります。私が理解しているように、1つの大きな連続ディスクの読み取りと、タイトなループでの多くの読み取りのように、事前に多くの作業を行っています。

プロファイリングに関しては、NetBeansに組み込まれているプロファイラーが好きです。始めるのは本当に簡単です。 :-)

1
Jubal

プロファイリングについて話すことはできませんが、Javaアプリケーションの開発経験から、BufferedInputStream、StringBufferのいずれかのバッファークラスを使用すると、アプリケーションが非常に高速になることがわかりました。そのため、私は最小のファイルや文字列操作にも使用できます。

1
Jason McCreary
    import Java.io.*;
    class BufferedInputStream
    {
            public static void main(String arg[])throws IOException
            {
                FileInputStream fin=new FileInputStream("abc.txt");
                BufferedInputStream bis=new BufferedInputStream(fin);
                int size=bis.available();
                while(true)
                {
                        int x=bis.read(fin);
                        if(x==-1)
                        {
                                bis.mark(size);
                                System.out.println((char)x);
                        }
                }
                        bis.reset();
                        while(true)
                        {
                                int x=bis.read();
                                if(x==-1)
                                {
                                    break;
                                    System.out.println((char)x);
                                }
                        }

            }

    }
0
Octavians