These threads are always slower than the C-API functions - a fairly common misconception, since by default they are synchronized with the C-layer. So yes, this is a feature, not a mistake.
Without sacrificing type safety (and readability, depending on your taste), you probably get performance with threads using:
std::ios_base::sync_with_stdio (false);
Small indicator:
#include <cstdio> #include <iostream> template <typename Test> void test (Test t) { const clock_t begin = clock(); t(); const clock_t end = clock(); std::cout << (end-begin)/double(CLOCKS_PER_SEC) << " sec\n"; } void std_io() { std::string line; unsigned dependency_var = 0; while (!feof (stdin)) { int c; line.clear(); while (EOF != (c = fgetc(stdin)) && c!='\n') line.push_back (c); dependency_var += line.size(); } std::cout << dependency_var << '\n'; } void synced() { std::ios_base::sync_with_stdio (true); std::string line; unsigned dependency_var = 0; while (getline (std::cin, line)) { dependency_var += line.size(); } std::cout << dependency_var << '\n'; } void unsynced() { std::ios_base::sync_with_stdio (false); std::string line; unsigned dependency_var = 0; while (getline (std::cin, line)) { dependency_var += line.size(); } std::cout << dependency_var << '\n'; } void usage() { std::cout << "one of (synced|unsynced|stdio), pls\n"; } int main (int argc, char *argv[]) { if (argc < 2) { usage(); return 1; } if (std::string(argv[1]) == "synced") test (synced); else if (std::string(argv[1]) == "unsynced") test (unsynced); else if (std::string(argv[1]) == "stdio") test (std_io); else { usage(); return 1; } return 0; }
With g ++ -O3 and a large text file:
cat testfile | ./a.out stdio ... 0.34 sec cat testfile | ./a.out synced ... 1.31 sec cat testfile | ./a.out unsynced ... 0.08 sec
How does this relate to your case. Change this test toy, add more tests and compare, for example. something like std::cin >> a >> b >> c with scanf ("%d %d %d", &a, &b, &c); . I guarantee that with optimization (i.e., not in debug mode), differences in performance will be negligible.
If this does not saturate your needs, you can try other approaches, for example. first reading the entire file (may or may not bring more performance) or memory cards (which is not a portable solution, but they have large desktops).
Update
Formatted Input: scanf vs. streams
#include <cstdio> #include <iostream> template <typename Test> void test (Test t) { const clock_t begin = clock(); t(); const clock_t end = clock(); std::cout << (end-begin)/double(CLOCKS_PER_SEC) << " sec\n"; } void scanf_() { char x,y,c; unsigned dependency_var = 0; while (!feof (stdin)) { scanf ("%c%c%c", &x, &y, &c); dependency_var += x + y + c; } std::cout << dependency_var << '\n'; } void unsynced() { std::ios_base::sync_with_stdio (false); char x,y,c; unsigned dependency_var = 0; while (std::cin) { std::cin >> x >> y >> c; dependency_var += x + y + c; } std::cout << dependency_var << '\n'; } void usage() { std::cout << "one of (scanf|unsynced), pls\n"; } int main (int argc, char *argv[]) { if (argc < 2) { usage(); return 1; } if (std::string(argv[1]) == "scanf") test (scanf_); else if (std::string(argv[1]) == "unsynced") test (unsynced); else { usage(); return 1; } return 0; }
Results:
scanf: 0.63 sec unsynced stream: 0.41