Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Back in the old days (1970-1980) you could pretty much predict the performance of an algorithm by counting floating point divides.</p> <p>That is no longer true today. However there is a similar rule you can use to estimate performance today:</p> <blockquote> <p>Count the number of trips to the heap: both <code>new/malloc</code> and <code>delete/free</code>.</p> </blockquote> <p>Given:</p> <pre><code>std::string to_string(const A&amp; a) { std::string s; // fill it up return s; } std::string s = test(); </code></pre> <p>I count 1 new, assuming you don't reallocate <code>s</code> internal to <code>to_string()</code>. That one allocation is done as you put data into <code>s</code>. I know that <code>std::string</code> has a fast (allocation-free) move constructor. So whether or not RVO happens is not relevant to estimating the performance of <code>to_string()</code>. There is going to be 1 allocation in creating the <code>s</code> outside of <code>to_string()</code>.</p> <p>Now consider:</p> <pre><code>void to_string(const A&amp; a, string&amp; out) { out = ... } std::string s; to_string(a, s); </code></pre> <p>As I've written it, it still consumes 1 memory allocation. So this is about the same speed as the return-by-value version.</p> <p>Now consider a new use-case:</p> <pre><code>while (i_need_to) { std::string s = to_string(get_A()); process(s); update(i_need_to); } </code></pre> <p>According to our previous analysis the above is going to do 1 allocation per iteration. Now consider this:</p> <pre><code>std::string s; while (i_need_to) { to_string(get_A(), s); process(s); update(i_need_to); } </code></pre> <p>I know that <code>string</code> has <code>capacity()</code>, and that capacity can be recycled over many uses in the above loop. The worst case scenario is that I still have 1 allocation per iteration. The best case scenario is that the first iteration will create capacity that is large enough to handle all other iterations, and that the entire loop will only do 1 allocation.</p> <p>The truth will likely lie somewhere in between the worst and best case scenarios.</p> <p>The best API will depend upon the use cases you think your function will most likely be in.</p> <p>Count allocations to estimate performance. And then measure what you've coded up. In the case of <code>std::string</code>, there will likely be a short string buffer that may impact your decision. In the case of <a href="http://libcxx.llvm.org" rel="nofollow">libc++</a>, on a 64 bit platform, <code>std::string</code> will store up to 22 <code>char</code> (plus the terminating null) before it makes a trip to the heap.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload