3 ms·
Most often you can pass stack values to and from functions without copying. This is because of move constructors, and named return value optimization. Often its
by petke 11y ago
Most often you can pass stack values to and from functions without copying. This is because of move constructors, and named return value optimization. Often its slower to use pointers (the indirection).
For instance this does not do any expensive copies:
std::string getStr() {
auto huge_str = getDatabaseDump();
return huge_str;
}
void readStr(const std::string& str ){
//read str..
}
int main() {
auto str = getStr();
readStr(str);
}
- pjc50 11y agoBut std::string is a wrapper for a heap allocation, and a reference also incurs the same indirection cost as a pointer?
- petke 11y agoYes that's true. Internally a lot of library types use heap allocation. Most well designed libraries avoid it if they can, but sometimes the object is simply too large for the stack. For many library types its a undocumented implementation detail we dont know about. We as users of that library type should not additionally put that object on the heap though, if we dont have too. Its simply unnecessary. Its makes for one extra unnecessary pointer indirection, it adds unnecessary reference counting if using smart pointers, or unnecessary manual memory management if we use raw pointers. It complicates the interface for our functions if we have to wrap types in smart pointers. As for c++ references. Yes that's true. As I understand it they are implemented as pointers internally by compilers. But in important ways they behave more like values, rather than pointers. As in if you copy or assign to them, they copy or assign the value (not the pointer). If you take their address they give the address of the value (not the pointer). Because of this there are not as many pitfalls to using them as there is with pointers. I see them mostly just as aliases for values. In the example above I could have passed the string by value (instead of by reference) to the function. It would still not have done a expensive copy, because of copy elision optimisation. I probably should have done that. It looks a bit funny, and takes some getting used too. Relevant: https://web.archive.org/web/20140205194657/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ https://web.archive.org/web/20140205194657/http://cpp-next.c...
- jupp0r 11y agoThe effects you describe are mainly caused by copy elision (https://en.m.wikipedia.org/wiki/Copy_elision https://en.m.wikipedia.org/wiki/Copy_elision) While move semantics certainly improve performance, they are still expensive in many cases, and it's very hard to make assumptions on their performance without detailed measurements. The problem with copy elision is that it's an optional compiler optimization and you have to check if the compiler applies it to you particular piece of code. That doesn't scale for large code bases (nor for small ones imho).
- CyberDildonics 11y agoThat isn't about value semantics, what you are describing is a combination of copy elision and ownership.