一切都始于这个问题-> How to read blocks of data from a file and then read from that block into a vector?

为了最大程度地减少磁盘I / O操作,我进行了一些实验,以查看缓冲区的大小是否对程序所花费的时间有任何影响。

我使用了以下两个代码,一个是面向C的,另一个是C++(尽管两者都使用gcc编译):

面向C的代码:-

int buffer_size=1024;
FILE *file;
file = fopen(argv[1], "r");
FILE *out_file;
out_file = fopen("in", "w");
char out_buffer[2048];
setvbuf(out_file, out_buffer, _IOFBF, buffer_size);
char buffer[2048];
setvbuf(file, buffer, _IOFBF, buffer_size);
while (!feof(file))
{
 char sl[1000];
 fgets(sl, 140 , file);
 fputs(sl, out_file);

}

C代码给出了以下结果(对于14 mb文件):
Buffer_size      Time
10               18 sec
100              2 sec
1024             0.4 sec
10240            0.3 sec

(对于103 mb的文件)
1024             ~8 sec
5120             ~3 sec
10240            ~3 sec
15360            ~3 sec

它似乎在缓冲区大小约为5 mb时达到了饱和点。有什么特殊原因吗?

面向C++的代码:-
int buffer_size=1024;
ifstream in_file(argv[1]);
char in_buffer[buffer_size];
in_file.rdbuf()->pubsetbuf(in_buffer,sizeof(in_buffer));
ofstream out_file("in");
char out_buffer[buffer_size];
out_file.rdbuf()->pubsetbuf(out_buffer,sizeof(in_buffer));
while(!in_file.eof())
{
    char sl[1024];
    in_file >> sl;
    out_file << sl<<endl;
}

我的测试输入文件是一个14mb文件,具有1000000行。
Buffer_size      Time (~)
10               6.5 sec
100              6.5 sec
1024             6.5 sec

C++似乎根本不关心缓冲区大小。为什么?

而且,C++代码的速度要慢大约15倍(当C中的缓冲区大小为1 mb时)!
ifstream通常比FILE慢(SO上的其他答案似乎表明没有区别)吗?还是代码中有其他原因导致速度缓慢?

最佳答案

从根本上讲,花费在写作上的时间是由以下形式的公式估算的:

T = C1*nsyscalls + C2*nbytes

实际上,C1是一个非常大的常数(每个系统调用的成本),而C2是一个非常小的常数(每字节的成本)。缓冲区的大小会影响nsyscalls/nbytes比率的大小;较大的缓冲区使其更小。缓冲的目的是使nsyscalls相对于nbytes足够小,以使第二项占第一项,而您剩下T = (C2+epsilon)*nbytes。一旦缓冲区足够大以至于第二项占主导地位,进一步增加缓冲区大小将不会使您获得任何显着的性能提升。

10-06 06:03