c++ - 无法理解 C 和 C++ 中缓冲区大小的不同实验结果。 ifstream 也比 FILE 慢吗?

标签 c++ c memory buffer ifstream

一切都始于这个问题 -> 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。一旦缓冲区足够大以至于第二项占主导地位,进一步增加缓冲区大小不会给您带来任何显着的性能提升。

关于c++ - 无法理解 C 和 C++ 中缓冲区大小的不同实验结果。 ifstream 也比 FILE 慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15150451/

相关文章:

c++ - 序列化,没有库的整数,得到奇怪的结果

c++ - 奇怪的字符串初始化

C : confusion over a small piece of code - what is '&0x' ?

.net - 关于udione解决WebBrowser内存泄露的方法

c++ - 是否可以使用 SetupAPI 检索 .inf 文件中一行的键?

c++ - Qt 应用程序 : Simulating modal behaviour (enable/disable user input)

c - 为什么 fork() 之前的 printf() 甚至在 fork() 之后执行?

c - 当我在 GDB 中运行程序时,GDB 是如何显示程序的虚拟地址的?

c - 计算不同函数中保留的内存的函数

c++ - Protobuf对象在传递给动态库时损坏