Solved

How to append to std::string in linked list fashion?

Posted on 2004-08-12
8
540 Views
Last Modified: 2013-12-14
I think this is an extremely difficult question. Urgency can be measured in months.

Background:
I work in a large company that uses std::string as its string choice. The application we code is a database application, and it often does hundreds of thousands of appends to a single string for a single report (The format we output is XML). The data in a report can be anywhere from 1k, to about 1gig. My group has developed a wrapper around this template class, but when we pass a std::string to library, we can not pass our own class, so this problem needs to somehow be handled in the std::string class itself. Maybe via the allocator object.

Problem:
The problem is, these appends slow us down because of all the allocation and string copying that must be done each append. If we could somehow have std::string store all the appends in a linked-list, and then combine it once, when we need it, this would be an ideal solution. Any speed-ups that can be provided could be helpful though.

Thoughts:
We need this in the std::string itself because this is the only object we can pass to other libraries that need to read or write to the string. While we could make sure the string was concatenated before passing it outside of our code, this is very dangerous and tedious since it's easy to forget.

Allocating more space than needed would help, but wouldn't be an ideal solution since it would hamper performance. The large range in amount of data that can be returned makes it difficult to guess how much would be good since a single append is generally anywhere from 2 bytes to 400 bytes.

I wasn't able to understand how the allocator class could be overridden since we need to combine all the data when it is needed.
0
Comment
Question by:Crius
8 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
Comment Utility
>>While we could make sure the string was concatenated before passing it outside of our code,
>>this is very dangerous and tedious since it's easy to forget

Bu, that IMHO is the way to go. You could take out the tediousness and danger about forgetting about that by automating the task if you offer a conversion operator that is applies when these functions are called.

>>I wasn't able to understand how the allocator class could be overridden

See e.g the sample here, maybe that helps:

http://www.codeproject.com/vcpp/stl/blockallocator.asp ("A Custom Block Allocator for Speeding Up VC++ STL")
0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 50 total points
Comment Utility
FYI:
If you're compiling in VC++ 5.0/6.0, or 7.x, the std::string class that comes with these compilers are very inefficient.
Consider replacing the std::string class with another library, or using CString instead.

CString is far more efficient that the std::string that comes with VC++.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>The problem is, these appends slow us down because of all the allocation and string
>>copying that must be done each append.

IMHO, you should cosider addressing this differently all together.

I recommend you try using std::list<std::string> instead.

Exactly how are you appending the data?

Do you have example code?

It might be that you just need to tweek the append code.
0
 
LVL 4

Assisted Solution

by:anthony_w
anthony_w earned 200 total points
Comment Utility
SGI provide a rope class which supports addition without reallocating. I believe this is still part of STLPort (www.stlport.org), which is based on the original SGI implementation of the STL.

If you use your own custom class for handling the string building, then you can give it a conversion to std::string (either explicit, with a named function, or implicit with a conversion operator), which you can then call when you pass it to the external interface.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 3

Author Comment

by:Crius
Comment Utility
Thank you for these feedbacks. First I would like to address some of the problems encountered with some of these solutions:

Using std::string is a company-wide mandate, and can not be changed. We were using a far more efficient string class before, but we had to change our class to derive from std::string. This can not be changed. It is not up to our smallish group. In fact, this change to std::string is what is prompting this question, otherwise, there would not be any problems.

A conversion operator was considered, but most of our calls to external code pass by reference, and I couldn't figure out how to do a concatenation during a call if we pass by reference.

An example of our append code is as follows:
(where string1, string2, and string3 are std::string)
string1 += string2;
also
string1 = string2+string3;

If we can use conversion operators to guarantee we can concantenate our string when it gets passed outside our code (by pointer, by reference, and by copy) then this would be a perfect solution!!!

We *must* derive our class from std::string however, and this brought up the problem - while we are sure our functions are the only ones used in our code, we could be assured this would not be the case when we passed our string outside of our code. Doing a dir of our *.cpp files only, we have 33 megs of code. Our string class is used everywhere, so changing the way we call external functions (we are very chatty) would not be feasible. We really need an automatic way of doing it without changing the interface/calling.

A block allocator would help, but as stated in my original problem, we don't want to use much more memory than needed, and we use a ton of strings, and their sizes differ greatly. A linked list is a great way to go, and std::list is basically this. If only we could use this instead of std::string.

There are many great solutions out there, but we must use std::string. It's a flexible class it seems, although I really don't understand how it works. I am hoping there's a way to have std::string behave more like a linked list in implementation.
0
 
LVL 3

Author Comment

by:Crius
Comment Utility
jkr,

If you could supply me with the conversion operators that would automatically be called when we are calling a function with the std::string as an argument, I would be very happy to award you an A.

We need to handle the following 3 possibilities:
1) Passed by value
2) Passed by reference
3) Passed by pointer

Passed by value can be done via a custom copy constructor.
How do I do the other two?
0
 
LVL 3

Author Comment

by:Crius
Comment Utility
Oops, also for anthony_w - it looks like this is the way to go...

Since we are required to derive our class from std::string... Well, will a str::string conversion operator still work? Will it be called, or will the compiler just say, "Hey, you're already a std::string, so I won't call the conversion operator?".
0
 
LVL 3

Author Comment

by:Crius
Comment Utility
After some tinkering and testing I was able to prove that the compiler will not call a user-defined conversion operator if the object is already what you want.

IE: Creating a class that inherits from std::string will cause any std::string conversion operators in the class to never be called.

I admit this question was far too specific with too many restrictions placed on it:
1) I have to inherit from std::string.
2) I need to pass my string class to outside functions.
3) I want it to have fast appending, like a linked-list can provide.

As such, I doubt there is a solution. I will split the points according to how much effort I felt were put in. It's unfortunate most of my questions get the answer of "It can't be done" in the end, but I admit, I would have been shocked if someone had come up with a way to do this.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now