I\'m trying to comprehend how to improve the performance of this C++ code to bring it on par with the C code it is based on. The C code looks like this:
#inc
Update: I did some more testing and (if you have enough memory) there is a surprisingly simple solution that - at least on my machine with VS2015 - outperforms the c-solution: Just buffer the file in a stringstream.
ifstream input("biginput.txt");
std::stringstream buffer;
buffer << input.rdbuf();
point p;
while (buffer >> p) {
i++
}
So the problem seems to be not so much related to the c++ streaming mechanism itself, but to the internals of ifstream
in particular.
Here is my original (outdated) Answer: @Frederik already explained, that the performance mismatch is (at least partially) tied to a difference in functionality.
As to how to get the performance back: On my machine with VS2015 the following runs in about 2/3 of the time the C-solution requries (although, on my machine, there is "only" a 3x performance gap between your original versions to begin with):
istream &operator >> (istream &in, point &p) {
thread_local std::stringstream ss;
thread_local std::string s;
if (std::getline(in, s)) {
ss.str(s);
ss >> p.x >> p.y;
}
return in;
}
I'm not too happy about the thread_local variables, but they are necessary to eliminate the overhead of repeatedly dynamic memory allocation.
What's causing a significant difference in performance is a significant difference in the overall functionality.
I will do my best to compare both of your seemingly equivalent approaches in details.
In C:
Looping
In C++:
Looping
One way to improve performance that I'd suggest is very near of what Peter said in above comments. Use getline
inside operator>>
so you can tell about your data. Something like this should be able to give some of your speed back, thought it's somehow like C-ing a part of your code back:
istream &operator>>(istream &in, point &p) {
char bufX[10], bufY[10];
in.getline(bufX, sizeof(bufX), ' ');
in.getline(bufY, sizeof(bufY), '\n');
p.x = atof(bufX);
p.y = atof(bufY);
return in;
}
Hope it's helpful.
Edit: applied nneonneo's comment
As noted in the comments, make sure the actual algorithm for reading input is as good in C++ as in C. And make sure that you have std::ios::sync_with_stdio(false) so the iostreams are not slowed down by synching with C stdio.
But in my experience, C stdio is faster than C++ iostreams, but the C lib is not typesafe and extensible.