Reputation: 12755
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
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
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
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
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