声明fread如下:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Run Code Online (Sandbox Code Playgroud)
问题是:两个这样的调用的阅读性能是否存在差异fread:
char a[1000];
Run Code Online (Sandbox Code Playgroud)
fread(a, 1, 1000, stdin);fread(a, 1000, 1, stdin);它会读取1000字节一次,每次?
Kei*_*son 101
表现可能有差异,也可能没有差异.语义有所不同.
fread(a, 1, 1000, stdin);
Run Code Online (Sandbox Code Playgroud)
尝试读取1000个数据元素,每个数据元素长度为1个字节.
fread(a, 1000, 1, stdin);
Run Code Online (Sandbox Code Playgroud)
尝试读取1个1000字节长的数据元素.
它们是不同的,因为它fread()返回它能够读取的数据元素的数量,而不是字节数.如果在读取完整的1000个字节之前它到达文件结尾(或错误条件),则第一个版本必须准确指出它读取的字节数; 第二个失败并返回0.
实际上,它可能只是调用一个低级函数,它试图读取1000个字节并指示它实际读取的字节数.对于较大的读取,它可能会进行多个较低级别的调用.要返回的值的计算fread()是不同的,但计算的费用是微不足道的.
如果实现可以在尝试读取数据之前判断没有足够的数据可供读取,则可能存在差异.例如,如果您正在读取900字节的文件,则第一个版本将读取所有900个字节并返回900,而第二个版本可能无法读取任何内容.在这两种情况下,文件位置指示符都按成功读取的字符数提前,即900.
但总的来说,你应该根据你需要的信息选择如何调用它.如果部分读取并不比不读取任何内容更好,则读取单个数据元素.如果部分读取有用,则读入较小的块.
ken*_*ytm 14
这将是实施细节.在glibc中,两者在性能上是相同的,因为它基本上实现为(参考http://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iofread.c):
size_t fread (void* buf, size_t size, size_t count, FILE* f)
{
size_t bytes_requested = size * count;
size_t bytes_read = read(f->fd, buf, bytes_requested);
return bytes_read / size;
}
Run Code Online (Sandbox Code Playgroud)
注意C 和POSIX标准不保证size每次都需要读取完整的大小对象.如果无法读取完整对象(例如,stdin只有999字节,但您已请求size == 1000),则文件将保持在一个间隔终止状态(C99§7.19.8.1/ 2).
编辑:查看关于POSIX的其他答案.
freadgetc内部调用。在Minix次数getc被称为仅仅是size*nmemb那么多少次getc将被称为依赖于产品的这两个。所以无论fread(a, 1, 1000, stdin)和fread(a, 1000, 1, stdin)运行getc 1000=(1000*1)时间。这是fread来自 Minix的简单实现
size_t fread(void *ptr, size_t size, size_t nmemb, register FILE *stream){
register char *cp = ptr;
register int c;
size_t ndone = 0;
register size_t s;
if (size)
while ( ndone < nmemb ) {
s = size;
do {
if ((c = getc(stream)) != EOF)
*cp++ = c;
else
return ndone;
} while (--s);
ndone++;
}
return ndone;
}
Run Code Online (Sandbox Code Playgroud)