Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to reduce ostringstream malloc/free's?

I am writing an embedded app. In some places, I use std::ostringstream a lot, since it is very convenient for my purposes. However, I just discovered that the performance hit is extreme since adding data to the stream results in a lot of calls to malloc and free. Is there any way to avoid it?

My first thought was making the ostringstream static and resetting it using ostringstream::set(""). However, this can't be done as I need the functions to be reentrant.

like image 555
Johan Kotlinski Avatar asked Mar 01 '10 18:03

Johan Kotlinski


People also ask

Does StringStream allocate?

stringstream is constructed with dummy. This copies the entire string's contents into an internal buffer, which is preallocated.

What is string stream?

The StringStream class in C++ is derived from the iostream class. Similar to other stream-based classes, StringStream in C++ allows performing insertion, extraction, and other operations. It is commonly used in parsing inputs and converting strings to numbers, and vice-versa.


3 Answers

Well, Booger's solution would be to switch to sprintf(). It's unsafe, and error-prone, but it is often faster.

Not always though. We can't use it (or ostringstream) on my real-time job after initialization because both perform memory allocations and deallocations.

Our way around the problem is to jump through a lot of hoops to make sure that we perform all string conversions at startup (when we don't have to be real-time yet). I do think there was one situation where we wrote our own converter into a fixed-sized stack-allocated array. We have some constraints on size we can count on for the specific conversions in question.

For a more general solution, you may consider writing your own version of ostringstream that uses a fixed-sized buffer (with error-checking on the bounds being stayed within, of course). It would be a bit of work, but if you have a lot of those stream operations it might be worth it.

like image 144
T.E.D. Avatar answered Nov 08 '22 01:11

T.E.D.


If you know how big the data is before creating the stream you could use ostrstream whose constructor can take a buffer as a parameter. Thus there will be no memory management of the data.

like image 44
mmmmmm Avatar answered Nov 08 '22 03:11

mmmmmm


Probably the approved way of dealing with this would be to create your own basic_stringbuf object to use with your ostringstream. For that, you have a couple of choices. One would be to use a fixed-size buffer, and have overflow simply fail when/if you try to create output that's too long. Another possibility would be to use a vector as the buffer. Unlike std::string, vector guarantees that appending data will have amortized constant complexity. It also never releases data from the buffer unless you force it to, so it'll normally grow to the maximum size you're dealing with. From that point, it shouldn't allocate or free memory unless you create a string that's beyond the length it currently has available.

like image 38
Jerry Coffin Avatar answered Nov 08 '22 01:11

Jerry Coffin