grady
grady

Reputation: 12755

Creating a string of repeating chars and cache it?

I have this code here to create a string of X spaces.

private static string GetWhiteSpaceString(int howManySpaces)
{
    return new string(' ', howManySpaces);
}

How could I cache this string somehow, so its only created if the number of spaces changed for example? Is there a better way than keeping some global variable?

Thanks :)

Upvotes: 1

Views: 300

Answers (4)

Marc Gravell
Marc Gravell

Reputation: 1062915

You could create a static (synchronised) Dictionary<int,string> - or if you are caching all lengths up to a known size, just a string[] (faster and simpler; no need to synchronise either).

For example:

    static readonly Dictionary<int, string> cache
        = new Dictionary<int, string>();
    public static string GetSpaces(int count) {
        // deal with brain-dead cases first to avoid lock for short strings
        switch (count)
        { // note these are all interned etc
            case 0: return "";
            case 1: return " ";
            case 2: return "  ";
            case 3: return "   ";
            case 4: return "    ";
            case 5: return "     ";
            case 6: return "      ";
            case 7: return "       ";
            case 8: return "        ";
            case 9: return "         ";
            case 10: return "          ";
        }
        if(count < 0) throw new ArgumentOutOfRangeException("count");
        lock (cache) {
            string s;
            if (!cache.TryGetValue(count, out s)) {
                cache.Add(count, s = new string(' ', count));
            }
            return s;
        }
    }

Upvotes: 0

Guffa
Guffa

Reputation: 700372

The method that creates the strings is probably not the best place to cache them (if there is even a good reason to cache them at all). The code that is using the strings probably has more information about which strings could be reused.

If you cache the strings, they will be long lived objects. That means that they will probably be moved into the next generation memory heap. Moving an object from one heap to another means that it will be copied from one place in memory to another, so this is at least as much work as creating a new string.

In most cases it will be more efficient to just create new strings instead of caching them. The garbage collector is especially made to handle short lived objects efficiently.

Upvotes: 1

ilivewithian
ilivewithian

Reputation: 19702

Possibly something like this (only coded in the browser, might not work):

Dictionary<int, string> cache = new Dictionary<int, string>();
private static string GetWhiteSpaceString(int howManySpaces)
{
    if(cache.Keys.Contains(howManySpaces))
    {
       return cache[howManySpaces];
    }
    else
    {
        var text = new string(' ', howManySpaces);
        cache[howManySpaces] = text;
        return text;
    }
}

This might do what you want, but I'd be worried about memory use. I guess it depends on how much howManySpaces varies.

Upvotes: 1

decyclone
decyclone

Reputation: 30830

I don't think you would need to cache a String. .Net handles it pretty well.

But if you still want to proceed, why not create a of type Dictionary<int,string> to store generated strings and look into it before returning a new one?

Upvotes: 2

Related Questions