tag:blogger.com,1999:blog-7101933101966798446.post6405857854498445589..comments2024-03-28T10:33:06.910-07:00Comments on The View from Aristeia: std::string, SSO, and Move SemanticsScott Meyershttp://www.blogger.com/profile/05280964633768289328noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-7101933101966798446.post-87237061155851400482012-04-26T22:34:00.435-07:002012-04-26T22:34:00.435-07:00@Marmot: Yes, of course, thanks for pointing this...@Marmot: Yes, of course, thanks for pointing this out. I've fixed it in the post.<br /><br />ScottScott Meyershttps://www.blogger.com/profile/05280964633768289328noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-19809340473985073022012-04-26T18:41:44.148-07:002012-04-26T18:41:44.148-07:00std::array< 1000,double > should be
std::ar...std::array< 1000,double > should be <br />std::array< double,1000 >?Marmothttps://www.blogger.com/profile/13108806061190500764noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-83609648945581188802012-04-13T07:16:34.812-07:002012-04-13T07:16:34.812-07:00@Scott:
1. It should not be a surprise to anyone...@Scott: <br /><br />1. It should not be a surprise to anyone that the efficiency of copying a container depends on its content. <br /><br />2. If they have done C++-level close-to-the-metal programming with performance concerns for a while, they will be familiar with the idea that such correlations might be nonlinear and counterintuitive. <br /><br />3. Copying those 15 bytes is still the fasted you get without move semantics, so — as Herb already said — you haven't lost anything. There's just an area (which is already fast) where you might haven't gained something. <br /><br />4. If copying 15 bytes (that's just 2 doubles!) is of a performance concern to someone, they should not rely on guesses anyway, but profile and measure. If it then turns out that adding a '\0' to the string makes it faster, that's on par with strange things like adding NOPs into code making it faster. (see #2)<br /><br />5. On 64bit machines, copying a pointer and a std::size_t might be 16 bytes, too.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-73354569422852293792012-04-12T13:30:08.086-07:002012-04-12T13:30:08.086-07:00@Scott: I think you should re-read what I wrote be...@Scott: I think you should re-read what I wrote before you call it "blanket reasoning." It was qualified in at least two ways. I have never told anyone, "don't worry, be happy, copies are fast now" or "all copies have turned into moves." And I don't believe that anything I've said even sounds remotely like that.<br /><br />Also, allow me to quote an argument from Martin B. that showed up on comp.lang.c++.moderated today, one that I often forget to make myself:<br /><br />"You should consider the issue of aliasing. It may be cheaper to pass a 4-int rectangle by const reference, but using it may be more expensive because it's harder for the compiler to be sure it is not changed through an alias."<br /><br />The compiler doesn't generally optimize based on <b>const</b>ness because of aliasing and separate compilation. It's actually not <b>const</b> but pass-by-value that lets the compiler make the optimizations that most people are hoping for in those circumstances. <br /><br />I you're looking for a description that I won't object to of my position, use this one: <br />There were always good reasons to seriously consider value semantics—an approach whose benefits have been under-recognized, partly due to fear of copying costs—as a normal part of your programming practice, and there are even more good reasons to do so today.Dave Abrahamshttps://www.blogger.com/profile/11169343557510903330noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-6846806876777904022012-04-11T11:11:37.545-07:002012-04-11T11:11:37.545-07:00@Dave: Regarding "What's new is that lots...@Dave: Regarding "What's new is that lots of things that used to copy don't anymore, so we can stop reflexively distorting code (e.g. with "out parameters") to avoid copies in those cases where copies have become moves.", such blanket reasoning is precisely my concern. I agree that this is valid reasoning if you know that the type supports efficient moving, but not all types support efficient moving (again I mention std::array<1000, int>), and if you are writing a template, you typically don't know if the types involved support move at all. <br /><br />The prospective guideline I've been kicking around is "Assume that move operations are neither present nor cheap." If you know that the assumption does not hold for the types you are using, great, take advantage of that knowledge. But in the same way that we generally assume that copying is expensive unless we have specific information to the contrary, we should assume that moving is no cheaper than copying unless we somehow know better.Scott Meyershttps://www.blogger.com/profile/05280964633768289328noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-20520665258443643242012-04-11T10:56:32.083-07:002012-04-11T10:56:32.083-07:00@Scott: it's not that we don't have to pay...@Scott: it's not that we don't have to pay attention to the cost of copies—the cost of copying hasn't changed. What's new is that lots of things that used to copy don't anymore, so we can stop reflexively distorting code (e.g. with "out parameters") to avoid copies in those cases where copies have become moves.Dave Abrahamshttps://www.blogger.com/profile/11169343557510903330noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-72783545889185796572012-04-11T10:38:26.382-07:002012-04-11T10:38:26.382-07:00@LCID Fire: The small string optimization (SSO) is...@LCID Fire: The small string optimization (SSO) is a library-level optimization that's independent of machine architecture. Either the standard library that ships with your compiler implements it, or it doesn't.<br /><br />@all: Actually there are lots of tradeoffs here worth experimenting with. For example, if you have 8-byte pointers and can store 15 characters without dynamic allocation, once you <i>do</i> have to allocate memory, do you store the <b>end()</b> pointer in the local memory, which makes <b>size()</b> (and maybe some other things) faster, or in the dynamic memory, which makes move faster?Dave Abrahamshttps://www.blogger.com/profile/11169343557510903330noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-60338229960698437432012-04-11T06:35:14.706-07:002012-04-11T06:35:14.706-07:00I am wondering whether SSO is platform dependent o...I am wondering whether SSO is platform dependent or more precise, whether it also holds up on <i>embedded</i> devices like Smartphones (e.g. ARM) since the instruction set is different.Andreas Bergmeierhttps://www.blogger.com/profile/12101686426494263632noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-69839614157470625822012-04-11T00:35:14.930-07:002012-04-11T00:35:14.930-07:00@Herb: If std::string was implemented without SSO,...@Herb: If std::string was implemented without SSO, it would copy the pointer (usually 4 or 8 bytes) instead of the 16 bytes (in the worst case). It's not a huge difference, and it's always a constant time penalty since stack memory is fixed-sized (C++ doesn't support VLAs). So if I understand your argument, "small strings are almost as cheap to copy as to move"?<br /><br />It's easy to understand Scott's concern when programmers are dealing with objects that have a mix of large stack and free store memory - the penalty would still be the constant amount of stack that needs to be copied, but the move operation gives the illusion that it should happen much faster than what would be (I don't think this is a concern with any STL containers).John Ahlgrenhttps://www.blogger.com/profile/10214801661943672953noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-32179480191002609322012-04-10T23:00:30.318-07:002012-04-10T23:00:30.318-07:00@Herb: Your viewpoint is legitimate, of course, bu...@Herb: Your viewpoint is legitimate, of course, but the fact that the efficiency of move vis-a-vis copy is dependent on the value of the string is something that is likely to surprise many people, I think, especially in view of <a href="http://john-ahlgren.blogspot.com/2012/03/small-string-optimization-and-move.html" rel="nofollow">John Ahlgren's measurements</a> showing that adding a single character to a string can increase the speed of moving it by a factor of three. It's a peculiar definition of "optimized" when adding data to the payload improves its performance significantly.<br /><br />ScottScott Meyershttps://www.blogger.com/profile/05280964633768289328noreply@blogger.comtag:blogger.com,1999:blog-7101933101966798446.post-82379210599121392312012-04-10T22:48:02.785-07:002012-04-10T22:48:02.785-07:00I mostly agree, but I think this point needs some ...I mostly agree, but I think this point needs some clarification:<br /><br />> Case in point: std::string. It supports moves, but in cases where std::string <br />> is implemented using SSO (the small string optimization), small strings are <br />> just as expensive to move as to copy! <br /><br />I think the right thing to say here is, "small strings are just as cheap to copy as to move!" This is not a pedantic distinction -- the situation is that it does not benefit further from move because it is already optimized! There really is a difference between "copy is as fast as move" (correct here) vs. "move is as slow as copy" when copy is already not deep (i.e., not involving reallocations).Herb Sutterhttp://herbsutter.comnoreply@blogger.com