如何确定缓冲区的大小

时间:2017-04-03 21:17:58

标签: c file malloc buffer

我有一个程序,它的目的是从一些输入文本文件中读取,将所有可打印的字符(即32到126之间的ASCII)过滤到其他输出文本文件中。

我也得到了一个参数" DataAmount" - 这意味着我需要读取的数据量可能是1B,1K,1M,1G,80000B等。(任何自然数都可以是在单位之前)。

这不是输入文件的大小,它是我需要从输入文件中读取多少。如果输入文件小于DataAmount,我需要重新读取文件,直到我准确读取DataAmount字节。

对于过滤,我从输入文件读取到一些缓冲区。我从缓冲区过滤到可打印字符的其他缓冲区,并从该缓冲区写入输出文件(两个缓冲区的大小相同)。 / p>

问题是,如何确定这两个缓冲区的最佳大小,因此对read()和write()的调用最少?

(注意:我不会一次写入整个数据,因为它可能太大了,我一次都不会写每个字节。我只是从outbuff写到输出文件当缓冲区已满时。

目前,我构建的缓冲区大小仅取决于单位:

如果它是B或K,则大小为1024。

如果是M或G,则大小为4096。

这一点都不好,因为1B和100000B我的缓冲区大小相同。

我该如何改善这个?

3 个答案:

答案 0 :(得分:3)

我个人的经验是,只要您使用几千字节,缓冲区大小就没那么重要了。

正如您在问题中所提到的,进行系统调用会产生开销,因此一次执行I / O一个字符并不是非常有效,您可以通过读取和写入更大的块来减少开销。但是,还有其他事情需要花费时间,任何合理数量的缓冲都会使您的系统调用开销下降到大多数情况下需要的其他事情。此时,较大的缓冲区不会使程序显着加快。将缓冲区设置得太大也存在问题,因此您也可能会出错。

我不会像你那样使缓冲区大小动态。它为程序带来了不必要的复杂性。您可以通过运行具有不同缓冲区大小的程序来验证它,并查看它产生的差异。

对于要使用的实际值,stdio.h头文件定义宏BUFSIZ,它是stdio缓冲区的默认大小。该宏是一个合理的大小。

另请注意,如果您使用stdio函数来执行I / O,则它们已经提供了缓冲(如果您没有直接调用系统调用read()和write(),那么您可以使用stdio。)实际上没有理由将缓冲数据两次,所以你可以一次做I / O一个字符并让stdio缓冲区为你处理它,或者禁用stdio缓冲使用setvbuf()。

答案 1 :(得分:0)

如果你之前知道输入,你可以得到一些统计数据并获得平均值,所以它不是固定大小而是近似值。

但我建议您:不要担心readclose系统调用。如果您从输入读取的数据非常少而且缓冲区很高,则会浪费一些字节。如果你得到一个很大的输入并且有一点缓冲,你只需要做一些额外的迭代。

缓冲区的中等大小会很好。例如,512。

答案 2 :(得分:0)

确定单位后,确定单位数量是否需要额外的缓冲区大小。因此,一旦找到 B ,请检查该值。这样你就不必拆分较小的单位。

您可以对单位指标执行switch语句,然后根据该单位的数值在每种情况下进行处理。例如,对于 B 执行最大值的整数除法,并根据结果设置实际缓冲区大小(同样在switch / case序列中)。