fwrite() – 大小和计数对性能的影响

关于fwrite()中两个参数’size’和’count’的目的似乎有很多混淆。 我想弄清哪个会更快 –

fwrite(source, 1, 50000, destination); 

要么

 fwrite(source, 50000, 1, destination); 

这是我的代码中的一个重要决定,因为此命令将执行数百万次。

现在,我可以跳转到测试并使用提供更好结果的那个,但问题是该代码适用于多个平台。

所以,

  • 如何才能获得跨平台更好的答案?

  • fwrite()的实现逻辑会因平台而异吗?

我意识到有类似的问题( fread / fwrite将大小和计数作为参数的原理是什么? fwrite和写入大小的性能 )但是要明白这是关于同一问题的另一个问题。 在这种情况下,类似问题的答案是不够的。

性能不应该依赖于任何一种方式,因为任何实现fwrite的人都会增加大小和数量来确定要做多少I / O.

FreeBSD的fwrite.c的libc实现就是一个fwrite.c ,它完整地读取(include指令省略):

 /* * Write `count' objects (each size `size') from memory to the given file. * Return the number of whole objects written. */ size_t fwrite(buf, size, count, fp) const void * __restrict buf; size_t size, count; FILE * __restrict fp; { size_t n; struct __suio uio; struct __siov iov; /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ if ((count == 0) || (size == 0)) return (0); /* * Check for integer overflow. As an optimization, first check that * at least one of {count, size} is at least 2^16, since if both * values are less than that, their product can't possible overflow * (size_t is always at least 32 bits on FreeBSD). */ if (((count | size) > 0xFFFF) && (count > SIZE_MAX / size)) { errno = EINVAL; fp->_flags |= __SERR; return (0); } n = count * size; iov.iov_base = (void *)buf; uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; uio.uio_iovcnt = 1; FLOCKFILE(fp); ORIENT(fp, -1); /* * The usual case is success (__sfvwrite returns 0); * skip the divide if this happens, since divides are * generally slow and since this occurs whenever size==0. */ if (__sfvwrite(fp, &uio) != 0) count = (n - uio.uio_resid) / size; FUNLOCKFILE(fp); return (count); } 

如果你考虑返回值 ,那么两个参数的目的会变得更清楚, 返回值是成功写入/读取流的对象的数量:

 fwrite(src, 1, 50000, dst); // will return 50000 fwrite(src, 50000, 1, dst); // will return 1 

速度可能取决于实现,但我不希望有任何相当大的差异。

我想指出你的问题 ,最后在调用fwrite一次和多次调用fwrite以写入“in chunks”文件之间暴露了一个有趣的性能差异。

我的问题是微软的fwrite实现有一个错误,所以大于4GB的文件不能在一次调用中写入(它挂在fwrite )。 所以我不得不通过以块的forms编写文件来解决这个问题,在循环中调用fwrite直到完全写入数据。 我发现后一种方法总是比单个fwrite调用返回得更快。

我在Windows 7 x64中使用32 GB的RAM,这使得写入缓存变得非常激进。