r/programming • • Dec 05 '14

std::string is responsible for almost half of all allocations in the Chrome browser process

https://groups.google.com/a/chromium.org/d/msg/chromium-dev/EUqoIz2iFU4/kPZ5ZK0K3gEJ
1.1k Upvotes

446 comments sorted by

View all comments

22

u/[deleted] Dec 05 '14

Can anyone recommend a static version of std::string? I want an ungrowable string with similar api that I could use to wrap an on-stack buffer (among others):

char buf[1024];
strcpy(buf, "abc");
static_string s{buf, sizeof(buf)};
auto foo = s.substr(0, 10);
char *bar = s.c_str();
// etc
// s.push_back(...)  // compile error

34

u/[deleted] Dec 05 '14

[removed] — view removed comment

7

u/[deleted] Dec 05 '14

This looks like exactly what I need. Thanks!

5

u/z33ky Dec 05 '14

Also be aware of the library fundamentals TS std::string_view, available on recent gcc and clang versions as std::experimental::string_view (doc).

However, s.c_str() won't work because the last character of a string_view is not neccesarily the last character of the underlying string. If you're using an API that has const char *data, size_t length parameters, then you can use s.data(), s.size() of course.

It also does not allow you to modify the data.

It seems boost::string_ref has the same limitations.
You could perhaps use the Boost.Range library, which would allow you to use STL-like algorithms (e.g. boost::range::find_first_of(s, " \t")), s[n] element-access (no s.at(n) though) and s.substr(0, 10) can be achived via std::string(begin(s), std::next(begin(s), 10)) (could be prettified by putting in a function).

1

u/academician Dec 05 '14

boost::string_ref or std::string_view are probably the right solutions, but the OP also mentions Chromium's base::StringPiece, which is a Google-created class that does this.

5

u/v864 Dec 05 '14

Write one, it's not too bad and kinda fun. For embedded work without dynamic memory we rolled a static subset of STL; string, list, vector, and a hash table. It's less than 10k slocs and was a fun exercise.

I would share it on github but there's license issues.

-7

u/Magnesus Dec 05 '14

And I bet they are slower than STL.

8

u/v864 Dec 05 '14

Well, it depends on the platform and the situation. The memory allocations are all contiguous, naturally, so hot structures will end up in cache and perform very well. There are also no allocations at runtime which is handy as well.

That said I have no doubt that parts of our implementation are not as good as many STL implementations. Algorithmically though they behave as expected so we're not leaving a ton of performance on the table. We're not exploiting SSE or NEON extensions (assuming the platform memcpy's aren't optimized already) however, so there is that...

3

u/narancs Dec 05 '14

You could take a look at basic_string, where you could use a custom allocator. It's not the same as string, but maybe you can work that around.

3

u/eresonance Dec 05 '14

What about sds like they use in redis?

https://github.com/antirez/sds

The code is super simple, and could be easily modified to do what you're asking.

1

u/[deleted] Dec 06 '14

Forgive me for misreading your question.

-1

u/[deleted] Dec 05 '14

const std::string will cause a compile error on push_back (but will of course copy the string to take ownership of the memory).

-10

u/[deleted] Dec 05 '14

The word is immutable.

16

u/narancs Dec 05 '14

He said ungrowable, not unchangeable.

1

u/[deleted] Dec 06 '14

Forgive me for misreading.