Skip to content

Instantly share code, notes, and snippets.

@janpipek
Created March 24, 2015 10:45
Show Gist options
  • Save janpipek/c35482983dab3579e285 to your computer and use it in GitHub Desktop.
Save janpipek/c35482983dab3579e285 to your computer and use it in GitHub Desktop.
Testing copying speed in C++ using different methods
// Compile: g++ copyfile.cc -o copyfile -lboost_timer -lboost_system -lboost_filesystem -g
// Run: ./copyfile testfile destfile 100
#include <string>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/timer/timer.hpp>
#define ARGS const std::string& in, const std::string& out, uintmax_t size
typedef void (*fpointer)(ARGS);
using namespace std;
void copy_file_sendfile(ARGS) {
int read_fd;
int write_fd;
off_t offset = 0;
read_fd = open(in.c_str(), O_RDONLY);
write_fd = open(out.c_str(), O_WRONLY | O_CREAT, 0774);
sendfile(write_fd, read_fd, &offset, size);
close (read_fd);
close (write_fd);
}
void copy_file_cp(ARGS) {
std::stringstream ssCp;
ssCp << "cp " << in << " " << out;
int result = system(ssCp.str().c_str());
if (result) {
cout << "Error when copying.";
exit(-1);
}
}
void copy_file_stdio(ARGS) {
char* buffer = (char*)malloc(size);
FILE* fin = fopen(in.c_str(), "r");
FILE* fout = fopen(out.c_str(), "w");
fread(buffer, size, 1, fin);
fwrite(buffer, size, 1, fout);
fclose(fin);
fclose(fout);
free(buffer);
chmod(out.c_str(), 0774);
}
void copy_file_boost(ARGS) {
boost::filesystem::copy_file(in, out, boost::filesystem::copy_option::overwrite_if_exists);
}
void copy_file_stream(ARGS) {
ifstream src(in.c_str());
ofstream dst(out.c_str());
dst << src.rdbuf();
}
fpointer methods[] = {
copy_file_sendfile,
copy_file_cp,
copy_file_boost,
copy_file_stdio,
copy_file_stream
};
const char* method_names[] = {
"sendfile",
"cp",
"boost::copy_file",
"fread / fwrite",
"c++ streams"
};
int main(int argc, char** argv) {
int count = 50;
string in = argv[1];
string out = argv[2];
if (argc > 3) {
count = atoi(argv[3]);
}
uintmax_t size = boost::filesystem::file_size(in);
cout << "Copying a " << size << "B file " << count << " times:" << endl;
for (int mode = 0; mode < sizeof(methods) / sizeof(fpointer); mode++) {
cout << "Copying using " << method_names[mode] << "..." << endl;
boost::timer::auto_cpu_timer t;
for (int i = 0; i < count; i++) {
stringstream ss;
ss << out << "-" << mode << "-" << i;
string out2 = ss.str();
methods[mode](in, out2, size);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment