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

这段代码有很多bug:

  • 它使用new[]C++。
  • 它不会释放分配的内存。
  • 它总是循环block_size输入的字节,而不是bytes_read返回的fread().

此外,实际的直方图代码效率相当低,因为它似乎遍历每个字符以确定它是哪个字符。

更新:删除了feof()在 I/O 之前使用是错误的说法,因为那不是真的。感谢 Eric 在评论中指出这一点。

于 2013-01-28T15:13:30.917 回答
0

您没有说明您在哪个平台上运行它,以及您使用的编译时间参数。

当然,这fread()涉及一些开销,离开用户模式并返回。另一方面,hist[]您不是直接设置信息,而是遍历字母表。这是不必要的,如果不进行优化,每个字节都会产生一些开销。

hist[j-26]++我会用或类似的东西重新测试这个。

通常,如果您的缓冲区大小等于给定媒体的系统缓冲区大小,则将获得最佳时机。

于 2013-01-28T15:12:26.800 回答