This is not a question of premature optimization per se. On the garbage collector and memory in general, what would hundreds of ToUpper()
operations (many could be duplicated) do to a program, mainly in regard to the immutability of strings?
views:
89answers:
3Every .ToUpper()
call creates a new string. So, extra .ToUpper()
calls is definitely inefficient. It is prudent and professional to try to minimize as many unneeded and duplicated .ToUpper()
calls as possible.
string Nacho = "cheesy"
Nacho = Nacho.ToUpper()
Nacho = Nacho.Trim().ToUpper()
. . . creates a lot of string garbage.
However, if this code doesn't need to be extremely fast, you don't need to be too paranoid. Although each of these orphaned strings needs to be garbage collected, these local small strings are almost always picked up in the GC's partial collections, and the memory is returned very quickly. Make sure you have your strings declared in the most limited scope possible (for example, within a routine rather than at the class level).
Hundreds? Almost nothing in most cases, assuming they're not enormous strings and you've got a sensible amount of memory. Hundreds of millions may well have an impact.
Basically each call will need to create a new string (I don't think .NET detects that it's already upper case).
Unless this is the bulk of what you're doing, I wouldn't expect it to be a bottleneck - but profiling will help to verify that.
Each call to ToUpper
will create a new string instance, even if the contents is the same as the original, and even if the string already exists as an interned string literal.
So, the impact of hundreds of ToUpper
calls is that you create hundreds of string instances. If the strings are short, this is not a problem, especially if you only use the strings for a short time. The garbage collector is made to handle small, short lived objects efficiently.
Example:
// Interned string literals are the same instance:
string a = "asdf";
string b = "asdf";
Console.WriteLine(Object.ReferenceEquals(a, b)); // True
// ToUpper naturally creates a new instance if the content is changed:
string c = b.ToUpper();
Console.WriteLine(Object.ReferenceEquals(b, c)); // False
// ToUpper creates a new instance even if the content is unchanged:
string d = c.ToUpper();
Console.WriteLine(Object.ReferenceEquals(c, d)); // False
// ToUpper will not intern strings:
string e = "ASDF";
string f = e.ToUpper();
Console.WriteLine(Object.ReferenceEquals(e, f)); // False
// Dynamically created strings can be interned manually:
string g = String.Intern(f);
Console.WriteLine(Object.ReferenceEquals(e, g)); // True