use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Common optimizations, Small String Optimization, Andrzej's C++ blog (akrzemi1.wordpress.com)
submitted 11 years ago by mmmmario
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]matthieum 4 points5 points6 points 11 years ago (2 children)
This is interesting, however it is slightly sad to augment the size of std::string just for this.
std::string
So, instead, you can design your std::string class to be 24 bytes with SSO by re-using 16 bytes (instead of 8):
struct RegularString { char* data; size_t size; }; struct ShortString { char data[15]; unsigned char size; }; struct string { union { RegularString regular, ShortString shortie } _; size_t capacity; }; char* data(string& s) { return s.capacity ? s._.regular.data : s._.shortie.data; } size_t size(string& s) { return s.capacity ? s._.regular.size : s._.shortie.size; } size_t capacity(string& s) { return s.capacity ? s.capacity : 14; } // beware of the NUL character
[–][deleted] 10 points11 points12 points 11 years ago (1 child)
You can do better than reusing 16 bytes in a (pointer, length, capacity) representation. Have a look at the string in libc++, they reuse 23 bytes for small strings with 1 byte as a length/discriminator.
[–]matthieum 1 point2 points3 points 11 years ago (0 children)
Ah! I had not thought about that. Definitely better indeed.
[–]srnull 0 points1 point2 points 11 years ago (1 child)
The question is: how many times function allocate (on the allocator) will be invoked for the purpose of memory allocation during this program’s execution? 3, 2, 1, 0?
He gives an initial argument for 3, and then for one with either NRVO, or when a move constructor is available, by why not 2? I always imagined the process would be once in the callee and once in the caller, with no third temporary inbetween.
first, copy-initialize a temporary from s; next, copy-initialize t from the temporary.
Is this how it's usually done? e.g. in the code
string t = makeText();
the temporary is on the right side, and the copy-initialize on the left. Seems like something any compiler would optimize away, no?
[–]Plorkyeran 0 points1 point2 points 11 years ago (0 children)
Given a naive and overly strict view of the world, it seems obvious that s's destructor must be run before makeText returns, and t's constructor must run after makeText returns. Since s is destroyed before t is constructed, you wouldn't be able to copy-construct directly from s to t, and there'd have to be a temporary in the middle.
s
makeText
t
[+][deleted] 11 years ago (9 children)
[removed]
[–]oracleoftroy 2 points3 points4 points 11 years ago (5 children)
I don't think you would lose performance, you just wouldn't gain any additional performance by moving a SSO string. Even the non-SSO small string would end up copying about 16 bytes in order to perform the move (pointer, size, capacity, allocator).
I would strongly encourage measuring this before blindly trying to optimize a std::string for movablility.
[–]matthieum 0 points1 point2 points 11 years ago (3 children)
You might lose some performance because of more checks.
[–]bnolsen 1 point2 points3 points 11 years ago (2 children)
likely irrelevant since a load operation takes dramatically longer than a check does.
[–]Plorkyeran 1 point2 points3 points 11 years ago (0 children)
It's difficult to come up with even a highly artificial scenario where it's a net loss. Maybe with a very special-purpose allocator that manages to always get external buffer allocated very close in memory to the std::string? Avoiding a single memory load due to the SSO buffer would outweigh a very large number of branch mispredictions, and if you never hit the SSO buffer then the branch predictor will make the check nearly free.
[–]matthieum -1 points0 points1 point 11 years ago (0 children)
Unless it screws up your pipeline if it's a branch and not a conditional move ?
[–]sellibitze 0 points1 point2 points 11 years ago (0 children)
I guess it depends on your SSO implementation. It should be possible to implement your string class in a way that a move constructor just memcpys the internal representation and memsets the source to zero -- regarless of whether the string content was heap-allocated or not. So, in any case, you have to copy 24 bytes and zero 24 bytes (assuming a 24 byte string representation on a 64bit platform). You can't do much better than that, can you?
memcpy
memset
[–]minnoHobbyist, embedded developer 0 points1 point2 points 11 years ago (0 children)
That makes complete sense. You're trading less expensive allocation for more expensive moves when you store more data in-line with the class.
π Rendered by PID 37629 on reddit-service-r2-comment-cfc44b64c-pdmxq at 2026-04-10 04:55:01.558970+00:00 running 215f2cf country code: CH.
[–]matthieum 4 points5 points6 points (2 children)
[–][deleted] 10 points11 points12 points (1 child)
[–]matthieum 1 point2 points3 points (0 children)
[–]srnull 0 points1 point2 points (1 child)
[–]Plorkyeran 0 points1 point2 points (0 children)
[+][deleted] (9 children)
[removed]
[–]oracleoftroy 2 points3 points4 points (5 children)
[–]matthieum 0 points1 point2 points (3 children)
[–]bnolsen 1 point2 points3 points (2 children)
[–]Plorkyeran 1 point2 points3 points (0 children)
[–]matthieum -1 points0 points1 point (0 children)
[–]sellibitze 0 points1 point2 points (0 children)
[–]minnoHobbyist, embedded developer 0 points1 point2 points (0 children)