我有一个程序生成包含字符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字节的最佳块大小 - 这是不正确的。我的代码肯定有问题,但我找不到它。
感谢任何建议。
问候。
编辑:
本练习的目的是通过记录不同缓冲区大小的读取时间(加上计算时间)来演示最佳缓冲区大小。文件指针由调用代码打开和关闭。
答案 0 :(得分:2)
此代码中存在许多错误:
new[]
,即C ++。block_size
字节的输入,而不是bytes_read
返回的fread()
。此外,实际的直方图代码效率很低,因为它似乎遍历每个字符以确定它是哪个字符。
更新:删除了在I / O错误之前使用feof()
的声明,因为那不是真的。感谢Eric在评论中指出这一点。
答案 1 :(得分:0)
您没有说明您正在运行此平台,以及您使用的编译时参数。
当然,fread()
涉及一些开销,离开用户模式并返回。另一方面,您不是直接设置hist[]
信息,而是循环使用字母表。这是不必要的,如果没有优化,每个字节会产生一些开销。
我会用hist[j-26]++
或类似的东西重新测试一下。
通常情况下,如果缓冲区大小等于给定媒体的系统缓冲区大小,则可以实现最佳时序。