6 ms·
The (typical C++ stdlib) problem here is that things that look deceptively simple on the surface may result in a surprising amount of activity under the hood (e
by flohofwoe 4y ago
The (typical C++ stdlib) problem here is that things that look deceptively simple on the surface may result in a surprising amount of activity under the hood (e.g. you need to know how std::string is implemented internally, and that a copy operation may or may not be expensive, maybe depending on the length of the payload, compiler and stdlib implementation, etc etc...).
And while the fabled 'zero cost abstraction' often is able to clean up the mess (at the cost of high build times), a small and innocent looking change in the surface code may throw things out of whack again and suddenly you have an unexpected performance regression.
- bluGill 4y agoMost languages don't let you reason about such things. You just copy things around with no clue or care if it is fast or slow. Most problems don't need that level of reasoning, but when it matters C++ gives you a lot of power to ensure you can control when it happens.
- jay-barronville 4y agoI mean, 9x out of 10, the very reason to use a low-level language like C++ is precisely because you want or need to reason about such things, no?
- bluGill 4y agoHopefully. There are other low level tasks (device drivers) that you might not care, but need C++'s ability to get close to the hardware for, but in general C++ is for when you need both abstractions and the ability to control performance. (Rust, C, ada, and other such languages also play in this space as well, which is best is not something I can comment on)
- kllrnohj 4y agoWhat innocent looking change are you thinking of that becomes an issue as a result of this? If your function is currently taking a parameter by-value, and you replace it with std::optional<T>, you're still taking it by value and doing the exact same amount of copies. No (new) issues from optional. You only run into trouble if you do something like change `void foo(const T&)` to 'void foo(std::optional<T>)`. But in such a change, it's "clear" (insofar as C++ is ever clear about anything) you're replacing a reference parameter with a value parameter. I don't think this is surprising std::optional behavior? > The (typical C++ stdlib) problem here is that things that look deceptively simple on the surface may result in a surprising amount of activity under the hood It's literally exactly what it looks like. The C++ stdlib didn't complicate or obfuscate anything.
- cesarb 4y ago> What innocent looking change are you thinking of that becomes an issue as a result of this? In these contexts, the "innocent looking change" is usually something which pushes a method over an inlining threshold, so that something which used to be inlined no longer is, and a zero cost abstraction suddenly has a cost larger than zero.
- kllrnohj 4y agoThat can be about literally any change, how does std::optional meaningfully change things here to warrant calling out that you need care when using it specifically?
- rightbyte 4y agoIt adds a space overhead. A pointer is already an optional type by the 0 convention.
- kllrnohj 4y agoYeah but I'd file that under C++'s ABI problems category. I don't think anything in std::optional's spec requires that it has additional padding. It could have an optimized representation for known types of T & thus specialize T* to use nullptr as the sentinel instead of an extra boolean, similar to how std::vector specializes for bool (although that one is probably a mistake, but whatever). But unfortunately also optional references was never resolved & thus punted ( see https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html#rationale.refs https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n35... ), even though boost::optional supported them
- jay-barronville 4y agoThis is why I love the simplicity of C (C99 in particular). I remember back when I started learning C++, after years of experience writing C, I was admittedly turned on by the cool features like smart pointers, standard data structures, etc., but once I read/wrote any significant amount of C++ code, the “deceptively simple” code quickly turned me off and had me running back to C. Suddenly, nothing was what it seemed. With C, I could jump into a codebase, and within a few hours/days, I’d have decent enough understanding of what’s going on, whereas C++ had me constantly wondering . . . - If certain operators were being overloaded - How memory was being allocated in different sections, libraries, etc. - The different semantics of the various ways you can do the same thing (e.g., constructors) . . . the list goes on and on and on. I’m not trying to crap on C++, but for a low-level language, the simplicity of C is simply unmatched!
- kllrnohj 4y agoOther than operator overloads, you have all those same problems with C. Only with the extra "benefit" that the compiler won't help you with jack shit. C is not a simple language. You're either naive or lying to yourself if you think it is. But in this case C isn't even any different, so this tangent is irrelevant anyway. If you take a struct by value in C it, drum roll, copies it!
- jay-barronville 4y agoSorry, I beg to differ. C is a simple language. The overwhelming majority of issues I’ve encountered writing C code haven’t had anything to do with the language; most issues have turned out to be due to compiler, library, architecture, kernel, OS, etc.-related differences, peculiarities, and/or issues. C++, on the other hand, makes it incredibly easy to shoot yourself in the foot at the language level.
- rightbyte 4y ago> Sorry, I beg to differ. C is a simple language. The problem with C is that it so simple that it is simple to complain about it. Other languages hide their quirks deeper down and are harder to complain about.
- zabzonk 4y agoi have been using std::string for many, many years and have never needed to know how my specific standard libraries implement it. if i want to worry about performance, i do it by timing and profiling, not reading standard library code.
- secondcoming 4y agoReally, you didn't care that C++11 forbade Copy-On-Write for std::string, or you never cared about the Short String Optimisation length that each platform supports?
- zabzonk 4y agoreally, i didn't care. cow has always seemed like a mistake to me, and what am i going to do about sso? make my strings intentionally shorter? or longer?
- usefulcat 4y agoIn this example, you don't need to know how things (i.e. std::string) are implemented internally so much as you need to know whether or not they're expensive to copy. That's a pretty fundamental aspect of the language, if you care about performance. If you do care and know about the particular implementation, I guess you might counter by saying that a COW string would be cheap(ish) to copy, or ditto if the string is short and the implementation uses the small string optimization. But at a higher level it's a very good general rule to just avoid copying anything unless you know for sure that it's small and doesn't use dynamic allocation.