Re: [boost] [string] proposal

----- "Dean Michael Berris" <mikhailberis@gmail.com> wrote :
On Sat, Jan 29, 2011 at 8:07 PM, Ivan Le Lann <ivan.lelann@free.fr> wrote:
Dean Michael Berris wrote :
But c_str() doesn't have to be part of the string's interface.
*My* *guess* is that Artyom think that:
os_func ((s1 + s2 + s3 + ... + s100).c_str()); // s for std::string
is dramatically faster than:
os_func ((c1 + c2 + c3 + ... + c100).to_string().c_str()); // c for
"boost::chain"
And this is precisely my point as well: the one that uses boost::chain is perfectly suited for this kind of use case in both efficiency and clear-cut semantics. I for one don't like to make to_string() a member either -- I much rather make it a conversion operator so boost::chain (if we're going to call it that) can be used where interfaces take a std::string.
[Note: I'm all for chains/ropes/etc, only looking for corner cases] I definitely agree for my example, which is a pure rope demo. linearize(chain) can give a c_str at no cost for trivial chains, and is not heavier than std::string::operator+ for non-trivial chains. Cool. Now looking at Artyom example makes me consider the quite common case where the desired output is not c_str but std::string itself. Add move optimizations on top of that: func_taking_std_string ( /*linearize*/ (my_chain_func ())); func_taking_std_string ( (my_string_func ())); No matter the way you put it, you have one unnecessary allocation, because std::string has no move constructor from chain (yet). For people eventually throwing their boost::chain into std::string, we're basically killing all move/RVO optimizations. Am I missing something? Ivan

On Sun, Jan 30, 2011 at 1:00 AM, Ivan Le Lann <ivan.lelann@free.fr> wrote:
No matter the way you put it, you have one unnecessary allocation, because std::string has no move constructor from chain (yet). For people eventually throwing their boost::chain into std::string, we're basically killing all move/RVO optimizations.
That can be an issue that can also be mitigated by interning linearized strings. But that only amortizes the cost of linearization -- basically having a pointer to the linearized string part of the root or metadata block for each immutable string. I don't think though there's a way to get around the extra allocation to convert to std::string unfortunately. But the linearization can definitely be made amortized constant time. However, consider that the cost of copying a string is typically the same -- an extra allocation and an element-wise of memcpy.
Am I missing something?
Nope, the extra allocation will happen regardless, you're right. This is exacerbated when you have a huge chain that you want to linearize to a string and is then copied. For short <1 page's worth of strings, well I'm not too worried about the cost of an additional allocation. But when you want a string instead of a chain, you pay the price of conversion. Maybe someone else has a good idea how to address this? -- Dean Michael Berris about.me/deanberris
participants (2)
-
Dean Michael Berris
-
Ivan Le Lann