Performance difference between C and C ++ IO style files

I have always heard that file input / output operations in C ++ are much slower than the C-style input / output. But I didn’t find any practical links regarding how slow they really are, so I decided to test it on my machine (Ubuntu 12.04, GCC 4.6.3, ext4 partition format).

First I wrote a ~ 900 MB file on disk.

C ++ ( ofstream ): 163s

 ofstream file("test.txt"); for(register int i = 0; i < 100000000; i++) file << i << endl; 

C ( fprintf ): 12s

 FILE *fp = fopen("test.txt", "w"); for(register int i = 0; i < 100000000; i++) fprintf(fp, "%d\n", i); 

I expected such a conclusion, it shows that writing to a file is much slower in C ++ C. Then I read the same file using C and C ++ I / O. Which made me exclaim that when reading from a file there is practically no difference in performance.

C ++ ( ifstream ): 12s

 int n; ifstream file("test.txt"); for(register int i = 0; i < 100000000; i++) file >> n; 

C ( fscanf ): 12s

 FILE *fp = fopen("test.txt", "r"); for(register int i = 0; i < 100000000; i++) fscanf(fp, "%d", &n); 

So, why does it take so long to record using a stream? Or, why is reading using the stream so fast compared to writing?

Conclusion: The culprit is std::endl , as answers and comments pointed out. Change the line file << i << endl; in file << i << '\n'; reduced the operating time to 16 s from 163 s.

+21
c ++ c stream file-io
Jul 04 '13 at 10:35
source share
3 answers

You use endl to print a new line. This is the problem because it is more than just printing a new line - endl also flushes the buffer, which is an expensive operation (if you do this at each iteration).

Use \n if you mean this:

 file << i << '\n'; 

In addition, you need to compile your code in release mode (for example, enable optimization).

+24
Jul 04 '13 at 10:44
source share

No, C ++ I / O is not significantly slower than Cs. If anything, the modern implementation should be a little faster on formatted input / output, since you do not need to parse the format string, and formatting is instead determined at compile time through a chain of stream statements.

Here are a few caveats to consider when testing:

  • Compile with full optimization ( -O3 ) to get a fair comparison.
  • The right test should measure bias - in practice, this means that you need to repeat your tests and alternate them. At the moment, your code is not resistant to violations of background processes. You should also provide summary statistics of repeat runs to catch outliers that misrepresent estimates.
  • Disable synchronization of a C ++ stream with C streams ( std::ios_base::sync_with_stdio(false); )
  • Use '\n' instead of (flushing) std::endl
  • Don't use register declarations - it just doesn't matter, and modern compilers probably ignore it anyway.
+19
Jul 04 '13 at 10:47 on
source share

When working with large files with fstream be sure to set the stream buffer> 0 .

In contrast, disabling thread buffering significantly reduces performance. At the very least, the MSVC 2015 implementation copies 1 char at a time to filebuf when the buffer has not been set (see streambuf::xsputn ), which can make your application tied to a processor, which will lead to lower I / O rates.

 const size_t bufsize = 256*1024; char buf[bufsize]; mystream.rdbuf()->pubsetbuf(buf, bufsize); 

Here you can find the full sample application.

0
Aug 23 '16 at 10:06 on
source share



All Articles