Re: Efficient use of C++ Strings: Request for Comments
Nevin :-] Liber wrote:
In article <1170270806.203625.294360@a75g2000cwd.googlegroups.com>,
"Ion Gazta?aga" <igaztanaga@gmail.com> wrote:
In my opinion, C++ should get a new optimization that could transfrom
code like this:
my_str = get_str();
to
get_str(my_str)
They are not semantically equivalent. I use the former when I need a
strong exceptions safety guarantee. In your case, if get_str() throws,
my_str is self-consistent but has an indeterminate value. Taking into
account Indeterminate values make code more brittle.
I agree that the code is not equivalent. Anyway if you have:
try{
my_str = get_str();
}
catch(...)
{}
how do you know if the exception is bein thrown by get_str or my_str's
copy constructor? So I think my_str's integrity is lost anyway.
In my opinion, there is still a temporary to be eliminated from C++.
Even with RVO, we don't have optimal code.
This is premature optimization (as are most of the items brought up by
the OP). Efficiency at the cost of brittleness. Returning strings by
value is easy to get right; having the caller manage the space manually
just to save an allocation is easy to get wrong. That code had better
be a measured bottleneck before changing it.
I was just replying the statement: "I wouldn't avoid it especially
since in the future any CPU overhead will be eliminated on all
implementations with the rvalue reference semantics". Which is not
entirely true. The previous code in a loop and you can get hundreds of
allocation/deallocations.
std::vector<std::string> load_customers();
void update_customers ()
{
//customers_ is std::vector<std::string> member variable
customers_ = load_customers();
}
This code, even with move semantics, can lead to customers_.size() + 1
allocations and deallocations. Without move semantics you have
2*(customers_.size() + 1) allocations and deallocations. Take in care
that memory allocation is many times a linear operation, so have a
cuadratic algorithm in your code. Your code won't scale even if the
CPU gets faster.
Talking about premature optimization, I would say that returning
strings by value, specially in the standard library where the size of
the string is unknown, is premature pessimization. I never pass
expensive objects by value, so I avoid returning expensive objects by
value.
"stringstream" is the best example of a premature pessimization
design. Returning the string by value is so inefficient that one can
understand why stringstream is avoided many times and the unsafe
sprintf is used instead. If you want to avoid returning a const
reference to have more security, this function
//This function does not exist
stringstream.fill_str(std::string &str);
will always be more efficient than
std::string str = stringstream.str();
just try to use "stringstream.str();" in a big loop.
I tend to focus on correctness as long as the efficiency is "good
enough" (and "good enough" is different for different applications).
That depends on what's "good enough". Maybe the problem is that
nowadays "good enough" sets the bar too low. You just need to see how
some applications are getting more and more inefficient and use so
much resources to do exactly the same thing another application did
with 3 times less resources.
Regards,
Ion
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]