2

I'm making an app that converts images into textual RRR GGG BBB  string arrays.

It works very fast with small images, but when the pixel count of input image is very high, the app slows down progressively.

The application runs x,y loop through all the pixels of input image, scans each pixel and adds its RGB formatted values to the final string which will be saved as text after the whole image is scanned.

With help of built-in profiler I found out that the System.String.Concat(string,string) takes more and more time the bigger the final string gets.

I then tried making a temporary string that will save the result of calculations of 1 row and before entering the next row, add it to the final string. Now it works about ten times faster, but still closer to the end, performance drops.

But in the end all my test images are smaller than the real ones are going to be. How do I keep concatenation speed high with even bigger images?

1
  • What do you do with the string? Can you save/send a portion of it? Commented Apr 23, 2012 at 12:03

6 Answers 6

8

Use System.Text.StringBuilder:

var sb = new StringBuilder();
sb.Append(r);
sb.Append(g);
sb.Append(b);

string result = sb.ToString();

This class is designed especially for fast string concatenation. I don't know anything faster (for general case) that it.

Sign up to request clarification or add additional context in comments.

5 Comments

Open the link and scroll down :)
That's it, now it works even faster. Huge images are also processed fast enough.
For optimal performance, if you roughly know the size you need, include it in the constructor, eg new StringBuilder(sizeEstimate). It then preallocates the estimated size instead of having to resize too much if starting from the (possibly much smaller) default size.
@Will my final string consists of preformatted strings of equal length and the number is vertical*horizontal image dimensions, should it improve if I pre-allocate exact space needed when initializing? (could be about 6 million symbols in a 16384*32 image)
Yes, if you can easily precalculate the exact size, go for it! It also helps avoid memory fragmentation. A quick test shows approx 12%+ speed improvement, YMMV.
4

To elaborate on @abatishchev's answer:

When you concatenate strings, you're actually creating a new string instance for each concatenation, so you're allocating thousands (millions?) of tiny strings all the time. A StringBuilder, however, uses an internal character buffer to manage the string as it is built, and avoids these frequent allocations.

Usage is like this:

StringBuilder sb = new StringBuilder();
foreach (Pixel pixel in myPixels)
{
    sb.Append(ConvertToString(pixel));
}

string myString = sb.ToString();

Comments

3

As everyone said, yes, use StringBuilder.

BUT

If you already have the strings to concatenate in the form of some collection, String.Join() proved to be faster.

Just note that.

4 Comments

It would be surprising if String.Join is faster, considering the fact it uses StringBuilder internally, according to Reflector. EDIT: Strike that. It seems that some overloads of Join use their own unsafe implementations, and some use StringBuilder. Interesting.
I dug a bit more into string.Join, and it seems that if you have an existing array of strings (string[]), string.Join will use an internal unsafe implementation. However, if you have any other collection of strings (The IEnumerable<string> overload) or an object[], then string.Join will use a StringBuilder internally. Apparently they could squeeze some performance advantage when they know the strings are laid out sequentially in an array.
Makes sense. Either way, string.Join can only improve. But of course, of not in a collection beforehand - StringBuilder is the way to go.
By the way, turns out you can implement your own StringBuilder a lot more efficient than the framework one. Some improvements can be made on the framework StringBuilder which improve performance, although I don't remember the details.
2

Use String.Join("", myarray);

Comments

0

Use StringBuilder like this:

//add reference
using System.Text

//create string builder
StringBuilder sb = new StringBuilder();
//add items to it
sb.Append("some text");
sb.Append(" more text");

Comments

0

StringBuilder designed to work with huge and complex strings.

Comments

Your Answer

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.