Home  /  RSS  /  RSS Comments  /  Enter

When the memory allocation matters

8/10/11, by artyom ; Posted in: Benchmarks; 3 comments

There are many different bottle necks in C++ networking applications, many of them related to the architecture, the way system calls are used, the way application generates the data.

However at certain point applications reach the point when memory allocation becomes the bottle neck, this is especially relevant for the cases where text strings are widely used. And this is usually the case for all networking and web applications that finally need to deal with strings.

The old and good std::string has one limitation - it requires memory allocation for the chunk it represents. This is actually correct for almost any kind of string around whether they reference counted, immutable - all they allocate chunks of memory.

Consider situation, where I need to search against path /foo/bar/123 in some hierarchical structure like std::map that uses std::string as the key. So I need to find a path using after fetching two keys foo and bar from the path.

So basically for the function:

void find_path(std::string const &str);

The call:

find_path("/foo/bar/123");

Would need to:

So I've got three memory allocations and this is not matter whether these strings are mutable or immutable, reference counted or not.

CppCMS should handle such code in multiple places so how it solves this problem?

  1. Create a special object cppcms::string_key it holds inside a full std::string but also can be created explicitly from a pair of two char const * pointers that define a text in range [begin,end).

    What is important that in in the second case object does not copy the data but only references it and I'm as a user responsible to ensure that the text range remains valid as long as I use this object.

  2. Now we add an overload for the function above:

    void find_path(char const *str);
    void find_path(std::string const &str);
    

    And when we split the text into parts we use only "unowned-strings" such that creation of a strings /foo/bar/123, foo, bar would not require memory allocation at all.

It is a general line, but there are much more interesting tricks to deal with 0 or few allocation strings and streams, like creation of a small memory pools that release all strings in once, like using on stack storage for small text chunks and much more.

This technique is widely deployed in CppCMS 0.99.9 code and had allowed to improve performance of page generation by up to twice in some cases.

Now these tricks should be done careful as they rely on manual memory management so, unless you do something many-many times or you detect some bottle-neck in the application still stick with std::string as it is usually good enough. Memory allocation today is very fast, just don't abuse it.

Comments

Marius, at 8/12/11, 12:15 PM

As a C/C++ programmer myself I like this kind of approach. Optimizing is always fun and when you get significant improvements like 2x the initial performance then it's even better. I enjoyed reading this and it would be nice if you could post some more of these articles about optimization or programming in general. There's one thing that's not really clear ( at least for me ) from the article though. Why do you need to

Create a sub-string foo
Create a sub-string bar

? And how si the char * used instead. Maybe a little more in depth would be nice. I'm just curious. I did get the idea though and I like it. But as you say it is dangerous stuff.

artyom, at 8/13/11, 4:25 PM

Because std::map<std::string,std::string> allows to search entries with following function:

iterator find(std::string const &)

So you need to create a string

Marius, at 8/17/11, 12:32 PM

Ah , I see now... Didn't think of it.

Add Comment:

 
 the email would not displayed
 

You can write your messages using Markdown syntax.

You must enable JavaScript in order to post comments.

Pages

Categories