I'm doing something really simple: slurping an entire text file from disk into a std::string
. My current code basically does this:
std::ifstream f(filename);
return std::string(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
It's very unlikely that this will ever have any kind of performance impact on the program, but I still got curious whether this is a slow way of doing it.
Is there a risk that the construction of the string will involve a lot of reallocations? Would it be better (that is, faster) to use seekg()
/tellg()
to calculate the size of the file and reserve()
that much space in the string before doing the reading?
To be honest I am not certain but from what I have read, it really depends on the iterators. In the case of iterators from file streams it probably has no built in method to measure the length of the file between the begin and the end interator.
If this is correct it will operate by something similar to doubling it's internal storage size every time it runs out of space. In this case for n characters in the file there will be Log[n,2] memory allocations, and memory deletions, and n*Log[n,2] individual character copies, on top of just copying the characters into the string.
As Greg pointed out though, you might as well test it. As he said try it for a variety of file sizes for both techniques. Additionally you can use the following to get some quantitative timings.
this should do the trick for the timing.
What happens to the performance if you try doing that? Instead of asking "which way is faster?" you can think "hey, I can measure this."
Set up a loop that reads a file of a given size 10000 times or something, and time it. Then do it with the
reserve()
method and time that. Try it with a few different file sizes (from small to enormous) and see what you get.I benchmarked your implementation(1), mine(2), and two others(3 and 4) that I found on stackoverflow.
Results (Average of 100 runs; timed using gettimeofday, file was 40 paragraphs of lorem ipsum):
The implementations: