anon anon anon anon - 18 days ago 5
C++ Question

Efficient custom string creator

I'd like to know what's the most effective way of passing a custom string.
For example, I have this code segment:

outputFile << addSpace(data.len());


where

string addSpace(int n) {
string result("");
for (int i = 0; i < n; i++) {
result += ' ';
}
return result;
}


It is clear that the function is not so effective, since the string is returned by-val and then even used in a place where RValue could fit as well.
If N was fixed, say N=5, I could just use

outputFile << " "


but clearly that not the case.

So what would be the best solution?(regardless of this specific example of N white spaces, lets say for any parameter dependent string creation).
I thought about lambda functions but I'm not really sure.

Answer

It is clear that the function is not so effective, since the string is returned by-val

The string is local, so return by value is the only option. It is not really the return by value that makes the function less efficient, it's the fact that you create a new string in every call. The fact that you must return by value is simply a symptom of that design. However, the lack of efficiency is probably marginal unless you call the function a lot, with differing n (if caller uses same n, they can keep the returned string and reuse it).

You could of course pass a reference to a string to the function, let the function modify the string, and return the reference, which would indeed be (possibly only marginally) more efficient if the function is called many times, with the same argument string because then you avoid creating a new string every call. But then you need to manage that external string in the calling code, which would make the use of the function more complex, and therefore worse. And if you don't reuse the argument string, this isn't any more efficient anyway.

If you choose to use a new string for every instance, there is a simpler (and potentially more efficient, however even more marginally than difference with re-using a string) way than your function. Simply use the constructor of std::string:

outputFile << std::string(data.len(), ' ');

Not creating a string at all might be even more efficient for this particular case:

outputFile << std::setfill(' ') << std::setw(data.len()) << ' ';

So for the general case, the choice boils down to: The efficiency is crucially more important than a nice interface, and the strings can be reused - then pass a reference to string and modify. Otherwise returning a new string as in your example is better.