2

In my previous app I had an object like this:

class myType
{
public:
 int a;
 string b;
}

It had a lot of instances scattered everywhere and passed around to nearly every function.

The app was slow. Profiling said that 95% of time is eaten by the string allocator function.

I know how to work with the object above, but not how to work with string pointers.

class myType
{
public:
 int a;
 string* b;
}

They told me to use pointers as above.

  • How much faster is it with a string pointer?
  • What is copied when I copy the object?

  • How to the following using the class with the pointer:

Access the string value

Modify the string value without modifying the one in the object (copy?)

General things that change if I use string pointers?

asked Apr 19, 2010 at 13:12
4
  • 2
    Did you pass those myType instances around by value or by reference? Commented Apr 19, 2010 at 13:16
  • Finally a good case for a string reference. struct { int a; string& b; } Commented Apr 19, 2010 at 13:17
  • 1
    @kenny: holding strings by reference (or pointer) is probably the last resort. Controlling the lifetime of each instance can be PITA Commented Apr 19, 2010 at 14:09
  • If you want automatic memory management without copying the string content a bunch of times, how about using a boost::shared_array<char> to hold your character data? Commented Apr 20, 2010 at 3:12

3 Answers 3

6

It will actually probably be slower - you still need to create and copy the strings, but now you have the overhead of dynamic allocation on top. My guess is that you are copying your objects around too much - whenever you call a function, your myType objects should be passed as const references, wherever possible, not by value:

void f( const myType & mt ) {
 // stuff
}

If you actually need to change mt, you would have used a non-const reference - this is also less expensive than passing a value and returning a new value with modified fields.

answered Apr 19, 2010 at 13:18

Comments

3

I think using a pointer like this is a bad idea. Instead, look at how your myType is being used instead. In particular, instead of this:

void foo(myType a)
{
 // ...
}

Consider this:

void foo(myType const &a)
{
 // ...
}

In the former case, a copy of myType needs to be created to pass to the function foo(), in the second, no copy is needed, since a reference is passed instead (it's marked as const so that you can be sure foo() doesn't try to modify it - giving you (almost)the same behaviour as the first method).

There are probably other things you could change, but my guess is that doing this would give you the most bang for your buck (and it's a pretty mechanical change, so hopefully not too much chance of problems being introduced)

answered Apr 19, 2010 at 13:19

Comments

1

To add to the other answers, you also should be making sure any member functions of that class that pass a string are passing by const reference. For example, say your class constructor definition looks like this:

myType::myType(int a, string b)

Use this instead:

myType::myType(int a, const string& b)

So basically, go through all your function parameters throughout your project, and change string to const string&, and myType to const myType&. This alone should fix the majority of your performance issues.

Note: About dynamically allocating the string and passing as a pointer: This is not a good idea, as though it will lighten the performance load somewhat, you're going to be extremely vulnerable to memory leaks, which makes debugging a nightmare (in addition to being much more haphazardly destructive to your performance than running slow). As a general rule, I highly discourage passing naked pointers. There's almost always a better, safer alternative.

answered Apr 20, 2010 at 2:58

2 Comments

Using a raw pointer like this is probably a bad idea. But dynamically allocating the string and passing a pointer doesn't at all preclude the use of smart pointers such as boost::shared_ptr, which basically takes care of the memory leak problem.
Well, memory leaks aren't the only problem that can occur when passing pointers everywhere. Accidentally assigning a pointer to another when the data should have been copied; editing the data from a passed pointer when it shouldn't be; operating on a pointer that can be null in rare instances; these are all simple mistakes that can cause major bugs that are extremely difficult to track down.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.