<div dir="rtl"><div dir="ltr">Even if the memory overhead is small, they do introduce code complexity in coordinating the SmallString and raw_svector_ostream and much runtime cost:</div><div dir="ltr"><br></div><div dir="ltr">raw_ostream::write() calls raw_svector_ostream::write_impl() and raw_ostream::copy_to_buffer().<br></div><div dir="ltr">raw_svector_ostream::write_impl() calls OS.reserve and SetBuffer. </div><div dir="ltr">SetBuffer calls SetBufferAndMode(). testing the BufferMode for every time and writing these three pointers.</div><div dir="ltr"><br></div><div dir="ltr">Every function has several code paths, adding to complexity and runtime cost. Due to this complexity, there are *additional* tests in raw_ostream::write() callers trying to take shortcuts to avoid calling write_impl()... these tests also take time.</div><div dir="ltr"><br></div><div dir="ltr">Essentially, what we are trying to achieve with SmallString SmallString + raw_svector_ostream is be much, much simpler than what we have now, along the lines Rafael suggested:</div><div dir="ltr"><br></div><div dir="ltr">if there is enough space write the string</div><div dir="ltr">else reallocate, copy and write the string.</div><div dir="ltr"><br></div><div dir="ltr">That's simpler and shorter code by order of magnitude than the combination have now, and a bonus - with a smaller memory footprint. What more can we ask for?<br></div><div dir="ltr"><br></div><div> </div></div><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2015-04-20 18:19 GMT+03:00 David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sun, Apr 19, 2015 at 7:40 AM, Yaron Keren <<a href="mailto:yaron.keren@gmail.com">yaron.keren@gmail.com</a>> wrote:<br>
> A very common code pattern in LLVM is<br>
><br>
> SmallString<128> S;<br>
> raw_svector_ostream OS(S);<br>
> OS<< ...<br>
> Use OS.str()<br>
><br>
> While raw_svector_ostream is smart to share the text buffer itself, it's<br>
> inefficient keeping two sets of pointers to the same buffer:<br>
><br>
> In SmallString: void *BeginX, *EndX, *CapacityX<br>
> In raw_ostream: char *OutBufStart, *OutBufEnd, *OutBufCur<br>
<br>
</span>Any reason to believe this inefficiency is significant/important?<br>
Given that these are never in long-lived containers, but generally<br>
just on the stack, it doesn't seem like the extra 3 pointers would be<br>
very costly in terms of overall performance.<br>
<span class=""><br>
><br>
> Moreover, at runtime the two sets of pointers need to be coordinated between<br>
> the SmallString and raw_svector_ostream using raw_svector_ostream::init,<br>
> raw_svector_ostream::pwrite, raw_svector_ostream::resync and<br>
> raw_svector_ostream::write_impl.<br>
> All these functions have non-inlined implementations in raw_ostream.cpp.<br>
><br>
> Finally, this may cause subtle bugs if S is modified without calling<br>
> OS::resync(). This is too easy to do by mistake.<br>
><br>
> In this frequent case usage the client does not really care about S being a<br>
> SmallString with its many useful string helper function. It's just<br>
> boilerplate code for raw_svector_ostream. But it does cost three extra<br>
> pointers, some runtime performance and possible bugs.<br>
><br>
> To solve all three issues, would it make sense to have raw_ostream-derived<br>
> container with a its own SmallString like templated-size built-in buffer?<br>
><br>
><br>
</span>> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
><br>
</blockquote></div><br></div>