0

文字 A ~ Z のランダム分布を含むファイルを生成するプログラムがあります。読み取りに最適なブロック サイズを決定するために、さまざまなバッファー サイズで fread を使用してこれらのファイルを読み取る (および各文字をカウントする) メソッドを作成しました。メソッドは次のとおりです。

int get_histogram(FILE * fp, long *hist, int block_size, long *milliseconds, long *filelen)
{
    char *buffer = new char[block_size];
    bzero(buffer, block_size);

    struct timeb t;
    ftime(&t);
    long start_in_ms = t.time * 1000 + t.millitm;

    size_t bytes_read = 0;
    while (!feof(fp))
    {
        bytes_read += fread(buffer, 1, block_size, fp);
        if (ferror (fp))
        {
            return -1;
        }
        int i;
        for (i = 0; i < block_size; i++)
        {
            int j;
            for (j = 0; j < 26; j++)
            {
                if (buffer[i] == 'A' + j)
                {
                    hist[j]++;
                }
            }
        }
    }

    ftime(&t);
    long end_in_ms = t.time * 1000 + t.millitm;
    *milliseconds = end_in_ms - start_in_ms;
    *filelen = bytes_read;

    return 0;
}

ただし、2 から 2^20 のブロック サイズを使用してバイト/秒とブロック サイズ (バッファー サイズ) をプロットすると、4 バイトの最適なブロック サイズが得られます。これは正確ではありません。コードに何か問題があるはずですが、見つかりません。

アドバイスをいただければ幸いです。

よろしく。

編集:

この演習のポイントは、さまざまなバッファー サイズの読み取り時間 (および計算時間) を記録して、最適なバッファー サイズを示すことです。ファイル ポインターは、呼び出し元のコードによって開かれ、閉じられます。

4

2 に答える 2

2

このコードには多くのバグがあります:

  • new[]C++ である を使用します。
  • 割り当てられたメモリは解放されません。
  • によって返されるblock_sizeのではなく、常に入力のバイトをループします。bytes_readfread()

また、実際のヒストグラム コードはかなり非効率的です。各文字をループしてどの文字であるかを判断しているように見えるからです。

更新feof(): I/O の前に使用することが間違っているという主張を削除しました。それは正しくないためです。コメントでこれを指摘してくれた Eric に感謝します。

于 2013-01-28T15:13:30.917 に答える
0

これを実行しているプラ​​ットフォームや、使用するコンパイル時のパラメーターについては言及していません。

もちろん、これにfread()はオーバーヘッドが伴い、ユーザー モードを終了して戻ります。一方、hist[]情報を直接設定する代わりに、アルファベットをループしています。これは不要であり、最適化を行わないと、バイトごとにいくらかのオーバーヘッドが発生します。

hist[j-26]++これをまたは同様のもので再テストします。

通常、バッファー サイズが特定のメディアのシステムのバッファー サイズと等しい場合に、最適なタイミングが得られます。

于 2013-01-28T15:12:26.800 に答える