为什么默认情况下只有文本字符串保存在实习池中?

gdo*_*ica 29 .net c# compiler-construction string clr

为什么默认情况下只有文字字符串保存在实习池中?

来自MSDN的示例:

String s1 = "MyTest";
String s2 = new StringBuilder().Append("My").Append("Test").ToString(); 
String s3 = String.Intern(s2); 
Console.WriteLine("s1 == '{0}'", s1);
Console.WriteLine("s2 == '{0}'", s2);
Console.WriteLine("s3 == '{0}'", s3);
Console.WriteLine("Is s2 the same reference as s1?: {0}", (Object)s2==(Object)s1); 
Console.WriteLine("Is s3 the same reference as s1?: {0}", (Object)s3==(Object)s1);

/*
This example produces the following results:
s1 == 'MyTest'
s2 == 'MyTest'
s3 == 'MyTest'
Is s2 the same reference as s1?: False
Is s3 the same reference as s1?: True
*/
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 57

简短的回答:实习文字字符串在运行时便宜节省了内存.实时非文字字符串在运行时昂贵,因此可以节省少量内存以换取常见情况.

运行中的实习字符串"优化"的成本不会为利益付出代价,因此实际上并不是优化.实习文字字符串的成本很低,因此确实可以带来好处.

我在这里更详细地回答你的问题:

http://blogs.msdn.com/b/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx

  • 实习文字字符串是否有*任何*运行时成本?根据我的理解,如果六个程序集各自使用文字字符串"Quack"至少一次,那么将创建六个字符串"Quack"的实例 - 每个程序集一个,没有运行时打扰检查它们的内容.由于Reflection,.net通常必须假设任何函数都可以执行,因此可以访问任何文字字符串,因此文字字符串的生命周期将是它出现的程序集的生命周期.我认为"在运行时便宜"是轻描淡写. (2认同)
  • @supercat:你的理解是正确的; 文字字符串实习是在每个程序集的基础上完成的.至于你关于这种字符串生命周期的问题,我不知道答案.运行时我可以假设当没有对它的实时引用时释放这样的字符串,并在以后重新构建它; 你怎么能告诉参考不同?但它可以很容易地让它永远活着. (2认同)
  • @gdoron:我其实不知道这个问题的答案; 我自己也想知道同样的事情.我今天和一些CLR老定时器共进午餐; 我会看看他们中是否有人记得.我很高兴你喜欢这个博客. (2认同)

Mik*_*uel 23

语言设计者决定实际上每个中间字符串值的成本不值得性能成本.垃圾收集字符串的实习需要一个全局弱映射,当您拥有大量线程时,它可能成为瓶颈.

  • 为什么选择downvote?这个答案是对的. (7认同)