-1

So I have a std::string that is always used every time the function gets called.

void doSomething()
{
    ...
    std::string temp_str;
    ...    // bunch of codes which reads and writes to temp_str
}

Now I'm guessing, isn't it faster to change std::string temp_str to static std::string temp_str?

As mentioned here, I know that if the variable is allocated in the stack, what it does is just subtraction of the ESP, so it doesn't affect the performance much.

However, since the std::string allocates its buffer in heap, doesn't making it static make it reuse the memory? If the variable is automatic, isn't it a waste to new and delete memory every time the function gets called?

Well, this is not only about std::string. My question is:

Is static object in a function faster than automatic if it has a reusable resource (like dynamically allocated memory) as a member?

vbstb
  • 1,261
  • 1
  • 10
  • 14
  • 8
    Why don't you try and measure yourself? –  Jan 26 '18 at 14:18
  • 1
    For `std::string`, there's [SSO](https://stackoverflow.com/questions/10315041/meaning-of-acronym-sso-in-the-context-of-stdstring). – LogicStuff Jan 26 '18 at 14:20
  • 2
    Consider that `static` local variables have synchronization requirements due to guarantees that they are initialized exactly once at first use. – François Andrieux Jan 26 '18 at 14:20
  • 1
    Using a `static` would make the function non-reentrant and non-multithreadable, though you could use `thread_local` to get around the second problem. – François Andrieux Jan 26 '18 at 14:21
  • The function isn't reentrant with a static variable. –  Jan 26 '18 at 14:21
  • @manni66: Actually, C++ still thinks it is. Of course the semantics might very well change, but we can't say that without seeing code. If a particular value of `temp_str` is not needed across the reentrant call, the semantics are unaffected (e.g. if it's used only before or only after that call). – MSalters Jan 26 '18 at 14:53

1 Answers1

1

Do not make variables static for performance. Make a variable function-static only when you want your variable to have a function-static behavior.

since the std::string allocates its buffer in heap, doesn't making it static make it reuse the memory?

No, it does not. It makes your string hold on to the heap memory it has allocated across multiple invocations of the function in which it is declared.

This "saving" comes with consequences: if your function expects temp_str to be empty after the declaration, it must clear it out manually (which essentially cancels out any saving you may have had, and decreases readability). Otherwise the string would retain the last value that has been put into it.

There is a much worse consequence of the decision to make your variable static: since concurrent invocations of your function now share temp_str, your function becomes non-reentrant. This is a much larger issue than saving a few nanoseconds in string's constructor, don't do it.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • yes, I know the value will be retained, and I don't expect it to be empty. I 'overwrite' the value. Isn't it still faster than actually 'allocating'? – vbstb Jan 26 '18 at 14:32
  • @vbstb if you use move semantics (like a string returned from a function) then it has no difference. – Guillaume Racicot Jan 26 '18 at 14:35
  • @vbstb Yes, you do save on allocation if you keep re-using the same buffer, assuming you don't move it out, e.g. with [`std::move`](http://en.cppreference.com/w/cpp/utility/move). – Sergey Kalinichenko Jan 26 '18 at 14:35
  • well, I guess you are right about the non-reentrant thing (actually I didn't even know the word). But I have no intention of using multiple threads. – vbstb Jan 26 '18 at 14:39
  • @vbstb Sometimes non-reentrancy plays role even without concurrency, when the function becomes "stateful". Classic example is `strtok`: you cannot use it to partition tokens in a nested loop, even on a single thread. – Sergey Kalinichenko Jan 26 '18 at 14:42