用于从文件中读取的C ++最佳块大小

时间:2013-01-28 15:05:42

标签: c++ file-io

我有一个程序生成包含字符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字节的最佳块大小 - 这是不正确的。我的代码肯定有问题,但我找不到它。

感谢任何建议。

问候。

编辑:

本练习的目的是通过记录不同缓冲区大小的读取时间(加上计算时间)来演示最佳缓冲区大小。文件指针由调用代码打开和关闭。

2 个答案:

答案 0 :(得分:2)

此代码中存在许多错误:

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

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

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

答案 1 :(得分:0)

您没有说明您正在运行此平台,以及您使用的编译时参数。

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

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

通常情况下,如果缓冲区大小等于给定媒体的系统缓冲区大小,则可以实现最佳时序。