Re: What is the output of this program?
Alf P. Steinbach wrote:
* kanze:
Earl Purple wrote:
Alf P. Steinbach wrote:
push_back can be a tad inefficient on strings, because
strings are usually short, and for short sequences the
reallocations, assuming scaling of buffer size, are more
frequent and thus more costly.
I don't think it's the allocations that make push_back
inefficient, (you can do reserve() ahead and std::string
will often allocate enough anyway). What makes it
inefficient is that push_back has to do a bounds-check on
every call (how else will it know whether to reallocate?).
Much more efficient is resize().
I doubt it. I also doubt that either make a significant
difference.
Possibly you're talking about something entirely different
than the following program?
Possibly. There was explicit reference to the use of reserve;
if I add reserve to your pushbacking, the difference between the
two is very small on my machine (an AMD 64 bit here, with g++
4.0.1). It's also quite conceivable that for certain values, on
certain machines, the indexing version is actually slower---if
the resulting string is to large to fit in real memory, the
indexing version accesses each of the new elements twice, and
can cause thrashing.
I expressed two doubts. One concerned the "much"---the
difference between resize() and push_back() should never be very
large (except in the extreme case, where resize() causes
thrashing---but see the following). The second is whether it
will make a significant difference. In practice, I can't see
any program making enormous use of either variant here. To the
point where even if one version were ten times faster than the
other, I can't see it making significant difference in an actual
program.
As usual, two rules apply:
-- Don't use std::string (or any standard class) as a major
abstraction in your application. Standard classes are
designed intentionally with a more or less broad interface
(std::string is an extreme example) so that they will be
useful in a variety of different ways. At the application
level, you want a narrow interface, so that there are less
constraints if you have to optimize.
-- Do use std::string (and the other standard classes) to
implement these major abstractions. Use them in the most
natural, idiomatic way. If, later, the profiler shows that
there is a problem in one particular abstraction, you start
optimizing---perhaps replacing std::string with
std::vector<char> or std::deque<char>, or even (I've had the
case in real code) with std::vector<std::string>. Or just
compiling with optimizing turned on and debug checking
turned off---that makes a difference of a factor of 2 on my
system, which is far more than the difference between the
two algorithms.
Simple gratuious statements like the one I was responding to are
misleading. There are cases where you can make such statements:
for large data sets, quick sort is typically much more efficient
than bubble sort, for example. But this isn't one of them; at
best, it's a micro-optimization, which probably isn't worth
considering. (That said, if my application had a hard real-time
limit, I was 10% over, I'd already optimized, and the profiler
said that this is where I was spending the most time, I'd
certainly consider it. Try both, and use the fastest. If, of
course, I couldn't convince management to buy a machine that was
10% faster:-).)
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]