C# 实习生字符串文字误解?
我不明白: MSDN说 因此,具有特定值的文本字符串的实例 在系统中只存在一次 例如,如果将相同的文字字符串分配给多个 变量,则运行时检索对文本的相同引用 字符串,并将其分配给每个变量 此行为是否为默认行为(无实习生)?还是用实习的方法C# 实习生字符串文字误解?,c#,.net,string-interning,C#,.net,String Interning,我不明白: MSDN说 因此,具有特定值的文本字符串的实例 在系统中只存在一次 例如,如果将相同的文字字符串分配给多个 变量,则运行时检索对文本的相同引用 字符串,并将其分配给每个变量 此行为是否为默认行为(无实习生)?还是用实习的方法 如果是默认值,那么我为什么要使用intern?(该实例将已存在一次…) 如果不是默认值:如果我写入该行1000次: 控制台写入线(“拉拉”) 1)我的内存中会出现1000次“拉拉”吗?(不使用实习生…) 2) “拉拉”最终会被淘汰吗 3) “拉拉”已经被拘
- 如果是默认值,那么我为什么要使用intern?(该实例将已存在一次…)
- 如果不是默认值:如果我写入该行1000次: 控制台写入线(“拉拉”)
我有点困惑。字符串文本会自动插入(因此,如果您的代码包含“lalala”1000次,那么只会存在一个实例) 这样的字符串将不会得到GC'd,任何时候引用它们时,引用都将是插入的
string.Intern
适用于非文本的字符串-比如从用户输入或从文件或数据库读取的字符串,您知道这些字符串会经常重复,因此在整个过程中值得进行实习。实习是在幕后发生的事情,所以你作为一个程序员永远不用担心它。你通常不需要把任何东西放进游泳池,也不需要从游泳池里得到任何东西。就像垃圾收集:你永远不必调用它,或者担心它可能发生,或者担心它可能不会发生。(好吧,在99.999%的情况下,剩下的0.001%是当你做非常奇怪的事情时。)
编译器负责保存源文件中包含的所有字符串文本,因此“lalala”将被保存,而您无需执行任何操作,也无需对该问题进行任何控制。每当你在程序中引用“lalala”时,编译器都会确保从实习生池中获取它,同样,你不必做任何事情,也不必控制这个问题
实习生池包含或多或少固定数量的字符串,通常大小非常小(仅为.exe总大小的一小部分),因此它们从不被垃圾收集并不重要
编辑 插入字符串的目的是大大缩短某些字符串操作(如Equals())的执行时间。
String
的Equals()
方法首先通过引用检查字符串是否相等,速度非常快;如果引用相等,则立即返回true
;如果引用不相等,并且字符串都是内部的,那么它会立即返回false
,因为它们不可能相等,因为内部池中的所有字符串彼此不同。如果上述条件均不成立,则进行逐字符串比较。(实际上,它甚至比这更复杂,因为它还检查字符串的哈希代码,但在本次讨论中让我们保持简单。)
因此,假设您正在从字符串s
中的文件读取令牌,并且您有一个如下形式的switch语句:
switch( s )
{
case "cat": ....
case "dog": ....
case "tod": ....
}
字符串文本“cat”、“dog”、“tod”都已被实习,但您将它们中的每一个都与未实习的s
进行比较,因此您没有从实习池中获益。如果您在switch语句之前实习s
,那么switch语句将执行的比较将快得多
当然,如果您的文件可能包含垃圾,那么您不想这样做,因为将大量随机字符串加载到intern池肯定会破坏程序的性能,并最终耗尽内存。那么我为什么要使用
string.intern(“拉拉”)呢
如果自动从池中获取它?我可以用“拉拉”…请澄清…:)toda.@RoyiNamir-添加了一些关于string.Intern
的信息。希望澄清一点。一如既往,谢谢-第二部分为我澄清了一些事情。@RoyiNamir-“aaa”
是一个字符串文本。它将被插入,而不会被GC'd。@RoyiNamir-字符串文字将是编译程序时存在于程序中的字符串。编译器确保从插入池获取它。
。。。那么我什么时候要显式使用string.intern???@Oded已经回答了这个问题。我将尝试在我的答案中给出一个例子。非常感谢您提供的扩展示例。