Live data from Hacker News

Std::string half of all allocations in the Chrome browser process

groups.google.com

31–40 of 170 posts

Re: Std::string half of all allocations in the Chrome browser process

#31
post #3

Earlier quoted context omitted.

The C++ string library cannot bind the string to the stack frame since it doesn't know how long it's going to live. I suppose the compiler might realize that however and replace dynamic allocation by a static one but I'm not sure it's allowed to do that.

Interestingly, with Rust, the borrow checker makes it statically safe to know when you can stack alloc.

You can also do it in a more limited set of cases in other languages using escape analysis. You can't provide it in all cases, but in a subset of cases you can show that the allocation never escapes a certain stack context, and therefore it's safe to stack-allocate. I believe the JVM does that in many cases.

Re: Std::string half of all allocations in the Chrome browser process

#32
post #16
post #2

I'm old enough that I actually programmed in Turbo Pascal 3 (around 1985) which of course produced quite fast code even for the speeds of the processors then (4 MHz processors were enough for everybody, not really, but that's what we had!). That Turbo Pascal had strings that were of the limited size, but they were able to use the stack, not the heap. I still don't understand that the library string in C++ can't use t…

C++'s std::string could store the first few characters inline, and only fall back to heap storage if the string is too big. I'd be surprised if some implementations don't do this already. TurboPascal's strings had a number of quirks. Maximum length was limited to 255 characters, but different string variables could declare different lengths in their types. Writing string functions that could work with any string requ…

It's called the short string optimization. It was used once but I am not sure if it is any more. C++11 move semantics may help a lot with string churning...

Re: Std::string half of all allocations in the Chrome browser process

#33
One of the recurring things I see in programming literature for the last 20 years or more is performance hits when using string. I've seen essays on this in at least four different programming languages.

You'd think it'd be simple, but it's not. String is an allocated buffer of unknown final size, and since it represents some kind of meaning in a human language, and since human languages have indeterminate length for conveying any one concept, concatentation is extremely common.

This is actually one of those cases where I like c better, warts and all. Whenever you use a string, you should carefully think about what you're going to do with it, and if at all possible allocate all you need up front. Beats the heck out of taking an unexpected GC call somewhere later when you weren't expeccting it.

Re: Std::string half of all allocations in the Chrome browser process

#34
post #2

I'm old enough that I actually programmed in Turbo Pascal 3 (around 1985) which of course produced quite fast code even for the speeds of the processors then (4 MHz processors were enough for everybody, not really, but that's what we had!). That Turbo Pascal had strings that were of the limited size, but they were able to use the stack, not the heap. I still don't understand that the library string in C++ can't use t…

C++ libraries can optimize smaller strings and store them on the stack. It's commonly known as short string optimization. I'm not sure how many libraries actually use SSO, but I think the three major vendors use something similar.

https://stackoverflow.com/questions/10315041/meaning-of-acro...

https://stackoverflow.com/questions/21694302/what-are-the-me...

Re: Std::string half of all allocations in the Chrome browser process

#35
post #15

folly::fbstring, a drop-in replacement for std::string, is part of the folly library that we (Facebook) open sourced a while back. It allocates small strings in-line and larger strings on the heap and has optimizations for medium and large strings, too. It's proven quite effective for us, particularly when used with jemalloc, which it conspires with for more optimal memory management. We use it as std::string for our…

Yeah, and if I want to use it I need to replace std::string all around my code. I can't use it for other libraries, unless I replace and recompile them. And tomorrow a new library comes I need to replace everything again. Your effort is commendable, and I know squeezing gains are important in the case of fb, but in the end it's just locking yourself in a library that should've been a second though/built in.

1. Find / replace, I'm sure the API is simple enough and performance gains are worth the effort.

3. You don't need to replace anything, ever - only if you feel like your string performance is lacking, and that particular new library satisfies your needs (in terms of effort vs performance gains). I don't get why people believe that whenever something new comes out they have to switch over, and as a result are terrified of innovation.

4. I disagree with the "should've been built in" statement; the default std::string implementation is good enough for most (like any std:: thing). Besides, std:string was designed 25+ years ago, over a dozen CPU generations ago; the demands of today are must different.

Re: Std::string half of all allocations in the Chrome browser process

#36

Earlier quoted context omitted.

Yeah, and if I want to use it I need to replace std::string all around my code. I can't use it for other libraries, unless I replace and recompile them. And tomorrow a new library comes I need to replace everything again. Your effort is commendable, and I know squeezing gains are important in the case of fb, but in the end it's just locking yourself in a library that should've been a second though/built in.

1. Find / replace, I'm sure the API is simple enough and performance gains are worth the effort. 3. You don't need to replace anything, ever - only if you feel like your string performance is lacking, and that particular new library satisfies your needs (in terms of effort vs performance gains). I don't get why people believe that whenever something new comes out they have to switch over, and as a result are terrifie…

I agree with most points, but

"std:string was designed 25+ years ago, over a dozen CPU generations ago; the demands of today are must different."

Sure, but you don't need to break the API for that

You can replace the allocator in a C program without changing malloc/free to something else, this might have been a design goal. This way you can go back and forth to it, run your tests again, compare performance again, etc

Re: Std::string half of all allocations in the Chrome browser process

#37
post #4

I've worked on a project that used all of these: std::string, QString, OString, char*. All were required by a different library that we needed. This is why a good string type should be in core language.

This is the problem with C++ (and in a certain part, with C) "Everybody" has their own C++ string (MFC, QT, several libraries, heck, even GObject library has their strings) Same with C Now, you won't see anybody reimplementing strings in Java. C#, Python, JS, etc Lessons learned, their strings work std:string is certainly a step forward and should be used for most projects today

"Lessons learned, their strings work"

Except that they don't. Either they are 'complete' but massive and thus slow, or they start as 'array of byte' and then their designers spend 10 years implementing a more 'complete' string type that is still fast enough and end up as #1 anyway.

Of course the C++ way where there is no string type that everyone uses sucks too, it's just that strings are almost impossible to get 'right' because there is no real 'right' and so many special cases that aren't apparent at first sight.

Re: Std::string half of all allocations in the Chrome browser process

#38
post #8
post #3

Earlier quoted context omitted.

The C++ string library cannot bind the string to the stack frame since it doesn't know how long it's going to live. I suppose the compiler might realize that however and replace dynamic allocation by a static one but I'm not sure it's allowed to do that.

> The C++ string library cannot bind the string to the stack frame since it doesn't know how long it's going to live. Surely some kind of string that lives on the stack can have its storage on the stack because the storage goes out of scope exactly when the object does. I think the only place you might run into trouble is if you try to `move` a stack-allocated string somewhere, because it'll invariably result in a co…

Without any compiler magic involved I don't think it's possible to implement that in C++ in a way compatible with the current std::string interface.

The problem is not the allocation of the std::string object itself, it's the allocation of the underlying buffer containing the string. std::string has a static size, the buffer itself is dynamically sized.

You could replace the heap alloc with something like calloc (or dynamically sized arrays) in the constructor but then the buffer would be tied to the stack frame of the constructor, not the calling scope (so the memory would become invalid as soon as the constructor returns).

Unless I'm missing something completely obvious the only way to implement that would be to ask for the caller to provide the buffer and let the string take ownership of it. It's definitely possible but it's not how std::string works and it's arguably more error-prone since unlike languages like rust there's no full blown lifetime checker in C++, so you'd have to make sure that the string object never outlives the supplied buffer.

Alternatively you might be able to supply a custom allocator to std::strings but here be dragons.

Re: Std::string half of all allocations in the Chrome browser process

#39
post #4

I've worked on a project that used all of these: std::string, QString, OString, char*. All were required by a different library that we needed. This is why a good string type should be in core language.

reminds me of the 100 functions perlism http://stackoverflow.com/questions/6016271/why-is-it-better-...

Re: Std::string half of all allocations in the Chrome browser process

#40

One thing I've learned from PHP's internals is that using reference-counted strings and copying on write is a fantastic idea. You can save an awful lot of memory and allocations, and simplify your code.

Copy on write is not at all helpful in a language like C++ where concurrency can be concerned.
Post reply on HN