【发布时间】:2011-01-30 19:42:15
【问题描述】:
这不是过早优化本身的问题。在一般的垃圾收集器和内存上,数百个ToUpper() 操作(许多可以重复)对程序有什么作用,主要是关于字符串的不变性?
【问题讨论】:
-
你可能应该尝试使用 ToUpperInvariant() 因为 ToUpper() 是文化敏感的。
这不是过早优化本身的问题。在一般的垃圾收集器和内存上,数百个ToUpper() 操作(许多可以重复)对程序有什么作用,主要是关于字符串的不变性?
【问题讨论】:
每次调用ToUpper 都会创建一个新的字符串实例,即使内容与原始字符串相同,即使该字符串已经作为内部字符串文字存在。
因此,数百个ToUpper 调用的影响是您创建了数百个字符串实例。如果字符串很短,这不是问题,特别是如果您只使用字符串很短的时间。垃圾收集器可以有效地处理小型、短暂的对象。
例子:
// 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
【讨论】:
数百?在大多数情况下几乎没有,假设它们不是巨大的字符串并且你有大量的内存。数以亿计的人可能会产生影响。
基本上每个调用都需要创建一个新字符串(我不认为 .NET 检测到它已经是大写了)。
除非这是您正在做的大部分工作,否则我不会预计它会成为瓶颈 - 但分析将有助于验证这一点。
【讨论】:
每个.ToUpper() 调用都会创建一个新字符串。所以,额外的.ToUpper() 调用肯定是低效的。尽量减少不必要和重复的.ToUpper() 呼叫是谨慎和专业的做法。
string Nacho = "cheesy"
Nacho = Nacho.ToUpper()
Nacho = Nacho.Trim().ToUpper()
。 . .创建了很多字符串垃圾。
但是,如果此代码不需要非常快,则无需过于偏执。尽管这些孤立的字符串中的每一个都需要进行垃圾回收,但这些本地小字符串几乎总是在 GC 的部分回收中被拾取,并且内存被很快返回。确保在尽可能有限的范围内声明字符串(例如,在例程中而不是在类级别)。
【讨论】: