<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 19, 2015 at 7:40 AM, Yaron Keren <span dir="ltr"><<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="rtl"><div dir="ltr">A very common code pattern in LLVM is</div><div dir="ltr"><br></div><div dir="ltr"><font face="monospace, monospace"> SmallString<128> S;</font></div><div dir="ltr"><font face="monospace, monospace"> raw_svector_ostream OS(S);<br></font></div><div dir="ltr"><font face="monospace, monospace"> OS<< ...</font></div><div dir="ltr"><font face="monospace, monospace"> Use OS.str()</font></div><div dir="ltr"><br></div><div dir="ltr">While raw_svector_ostream is smart to share the text buffer itself, it's inefficient keeping two sets of pointers to the same buffer:</div><div dir="ltr"><br></div><div dir="ltr"> In SmallString: void *BeginX, *EndX, *CapacityX<br></div><div dir="ltr"> In raw_ostream: char *OutBufStart, *OutBufEnd, *OutBufCur<br></div><div dir="ltr"><br></div><div dir="ltr">Moreover, at runtime the two sets of pointers need to be coordinated between the SmallString and raw_svector_ostream using raw_svector_ostream::init, raw_svector_ostream::pwrite, raw_svector_ostream::resync and raw_svector_ostream::write_impl.</div><div dir="ltr">All these functions have non-inlined implementations in raw_ostream.cpp. </div><div dir="ltr"><br></div><div dir="ltr">Finally, this may cause subtle bugs if S is modified without calling OS::resync(). This is too easy to do by mistake.</div><div dir="ltr"><br></div><div dir="ltr">In this frequent case usage the client does not really care about S being a SmallString with its many useful string helper function. It's just boilerplate code for raw_svector_ostream. But it does cost three extra pointers, some runtime performance and possible bugs.</div></div></blockquote><div><br></div><div>I agree the bugs are real (Alp proposed something a while back regarding this?), but you will need to provide measurements to justify the cost in runtime performance. One technique I have used in the past to measure these sorts of things I call "stuffing": take the operation that you want to measure, then essentially change the logic so that you pay the cost 2 times, 3 times, etc. You can then look at the trend in performance as N varies and extrapolate back to the case where N = 0 (i.e. you don't pay the cost).</div><div><br></div><div>For example, in one situation where I used this method it was to measure the cost of stat'ing files (sys::fs::status) across a holistic build, using only "time" on the command line (it was on Windows and I didn't have any tools like DTrace available that can directly measure this). In order to do this, I changed sys::fs::status to call stat N times instead of 1, and measured with N=1 N=2 N=3 etc. The result was that the difference between the N and N+1 versions was about 1-2% across N=1..10 (or whatever I measured). In order to negate caching and other confounding effects, it is important to try different distributions of stats; e.g. the extra stats are on the same file as the "real" stat vs. the extra stats are on nonexistent files in the same directory as the "real" file vs. parent directories of the "real" file; if these match up fairly well (they did), then you have some indication that the "stuffing" is measuring what you want to measure.</div><div><br></div><div>So e.g. if you think the cost of 3 extra pointers is significant, then "stuff" the struct with 3, 6, 9, ... extra pointers and measure the difference in performance (e.g. measure the time building a real project).</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="rtl"><div dir="ltr"><br></div><div dir="ltr">To solve all three issues, would it make sense to have raw_ostream-derived container with a its own SmallString like templated-size built-in buffer?</div><div dir="ltr"><br></div></div>
</blockquote></div><br></div></div>