Why is copying a file in C so much faster than C++? -


i've been working on large c++ project few weeks now. original goal use project learn c++11 , use pure c++ code , avoid manual allocation , c constructs. however, think problem going force me use c small function , i'd know why.

basically have save function copy large binary file separate location before make changes data in it. files cd images max size of around 700mb. here original c++ code used:

std::ios::sync_with_stdio(false);  std::ifstream in(infile, std::ios::binary); std::ofstream out(outfile, std::ios::binary);  std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(out));  out.close(); in.close(); 

this code when used 690mb file takes barely under 4 minutes complete. have ran multiple files , it's same result; nothing under 3 minutes. however, found following way ran little bit faster, still fast c:

std::ios::sync_with_stdio(false);  std::ifstream in(infile, std::ios::binary); std::ofstream out(outfile, std::ios::binary);  out << in.rdbuf();  out.close(); in.close(); 

this 1 took 24 seconds, it's still around 20 times slower c.

after looking around found needing write 80gb file , seeing write @ full speed using c. decided give try code:

file *in = fopen(infile, "rb"); file *out = fopen(outfile, "wb");  char buf[1024]; int read = 0;  //  read data in 1kb chunks , write output file while ((read = fread(buf, 1, 1024, in)) == 1024) {   fwrite(buf, 1, 1024, out); }  //  if there data left on write out fwrite(buf, 1, read, out);  fclose(out); fclose(in); 

the results pretty shocking. here 1 of benchmarks have after running multiple times on many different files:

file size: 565,371,408 bytes c  :   1.539s | 350.345 mb/s c++:  24.754s | 21.7815 mb/s - out << in.rdbuf() c++: 220.555s | 2.44465 mb/s - std::copy() 

what cause of vast difference? know c++ won't match performance of plain c, 348mb/s difference massive. there i'm missing?

edit:

i compiling using visual studio 2013 on windows 8.1 64-bit os.

edit 2:

after reading john zwinck's answer decided go platform specific route. since still wanted make project cross-platform threw quick example. not sure if these work on other systems besides windows, can test linux @ later date. cannot test osx, think copyfile looks simple function assume it's correct.

keep in mind need same #ifdef logic including platform specific headers.

void copy(std::string infile, std::string outfile) { #ifdef _win32 || _win64   //  windows   copyfilea(infile.c_str(), outfile.c_str(), false); #elif __apple__   //  osx   copyfile(infile.c_str(), outfile.c_str(), null, copyfile_data); #elif __linux   //  linux   struct stat stat_buf;   int in_fd, out_fd;   offset_t offset = 0;    in_fd = open(infile.c_str(), o_rdonly);   fstat(in_fd, &stat_buf);   out_fd = open(outfile.c_str(), o_wronly | o_creat, stat_buf.st_mode);    sendfile(out_fd, in_fd, &offset, stat_buf.st_size);    close(out_fd);   close(in_fd); #endif } 

first, should benchmark against copying same file using cli on same machine.

second, if want maximum performance need use platform-specific api. on windows copyfile/copyfileex, on mac os it's copyfile, , on linux it's sendfile. of (definitely sendfile) offer performance cannot achieved using basic portable stuff in c or c++. of them (copyfileex , copyfile) offer features such copying filesystem attributes , optional progress callbacks.

you can see benchmarks showing how faster sendfile can here: copy file in sane, safe , efficient way

finally, sad true c++ iostreams not fast c file i/o on many platforms. if care lot performance, may better off using c functions. i've encountered when doing programming contests runtime speed matters: using scanf , printf instead of cin , cout makes big difference on many systems.


Comments

Popular posts from this blog

c++ - How to add Crypto++ library to Qt project -

jQuery Mobile app not scrolling in Firefox -

How to use vim as editor in Matlab GUI -