4 ms·
It’s funny that every company gets to the point where they have to have their own std::string. I wonder if Facebook also traces their need back to the time when
by thedance 7y ago
It’s funny that every company gets to the point where they have to have their own std::string. I wonder if Facebook also traces their need back to the time when GNU std::string was copy-on-write and therefore completely useless. Google, I think, can trace their std::string to those dark days. Luckily c++11 effectively outlawed COW string implementations, so nobody need be subject to that horror show again.
- api 7y agoSo your own std::string means you have "arrived?"
- faitswulff 7y agoI'm not very good at systems programming, what makes a CoW std::string a bad thing? Memory overhead for a common data structure?
- yongjik 7y agoFrom what I've heard - COW means each string data may be pointed to by multiple objects, potentially being used by different threads. So every string operation requires thread synchronization, which can be quite expensive.
- kccqzy 7y agoThe language is fundamentally too weak to express the kind of reference and borrowing relationships demanded by CoW. Suppose I have a string and I take a reference to a character: std::string a = f(); // shared char& c = a.front(); Should the string be copied or not? One might argue, no taking a reference is different from "writing" so no copying, but one might also argue that reference can be used to change the string later, and the string doesn't know when this would happen so it has to pessimistically make a copy. You get bugs if you go with the former, and bad performance if you go with the latter.
- zelly 7y agoconst char& c = a.front(); Unfortunately the STL has an overload for the non-const version, which would cause this problem. It's hard to imagine the cases where you'd need a mutable reference to a single character. It can fit into the same register that the reference would live, so even as an immutable reference it doesn't make much sense.
- kccqzy 7y agoThat's not an answer. The STL has to have a non-const version that returns some kind of reference. Because C++ strings are mutable and even something like s[3] = 'h'; involves forming a mutable reference and then assigning its pointee. The way I think about it, to make CoW strings really usable in C++, you basically have to make strings immutable, like many newer languages like Python. That ship has sailed by the time standardization for C++ happened.
- cryptonector 7y agoConsidering jq's libjq's jv[1] C API is CoW and written in C, I'm a bit disinclined to believe that C++ is too weak to express a reasonable CoW API for strings. Instead, I suspect that std::string was too weak a design for that. [1] https://github.com/stedolan/jq/wiki/C-API:-jv https://github.com/stedolan/jq/wiki/C-API:-jv
- klmr 7y agoThe language is too weak to express it safely. CoW on mutable strings in C and C++ by necessity implies safety (or drastically performance-degrading) tradeoffs. By contrast, `jv` types are immutable so they can presumably implement CoW without compromising memory safety or correctness.
- thedance 7y agoA copy-on-write string is pretty similar to a shared_ptr to char. Like a shared_ptr, a shared string has to check whether it is the last referent when it goes out of scope. This introduces a point of contention on multi-core systems. A string like the one described in this article might not have to do anything in its destructor, whereas a shared string will need to atomically decrement a reference count. That’s a huge difference in cost. The benefit of a shared string is you might save some space. That’s fine but I think most programmers today will choose am explicitly shared type when they need it, and a fast string for most cases.
- SamReidHughes 7y agoAtomic operations needed on multi-core, and the stuff that leaks a non-const reference to raw memory, like casual read-only use of operator[], .begin(), .end(), forces a copy on shared objects and prevents the object from being shared in the future.
- OskarS 7y agoIn addition to what other people have said, the move semantics introduced in C++11 made a lot of the benefit of CoW moot: the point of CoW is to have a cheap copy operation, but most of those cheap copy operations can be replaced by even cheaper moves, often automatically by the compiler.
- acqq 7y agoDoes anybody know at which point exactly the GNU std::string implementation changed? Like “since version number N.N of the project X”?
- scatters 7y agoSince GCC 5.1. The change was and is done in a backward and forward compatible manner, using dual ABI: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_a...