实习生字符串字面量的误解
本文关键字:误解 字符串 实习生 | 更新日期: 2023-09-27 18:19:14
我不明白:
MSDN说http://msdn.microsoft.com/en-us/library/system.string.intern.aspx
因此,一个具有特定值的字面值字符串实例在系统中只存在一次
例如,如果将相同的字面值字符串赋值给多个变量时,运行时检索对字面量的相同引用从内部池中取出字符串,并将其分配给每个变量。
这个行为是默认的吗(没有实习生)?还是使用Intern方法?
-
如果是默认的,那么我为什么要使用intern呢?
-
如果它不是默认的:如果我写1000次这一行:
Console.WriteLine("lalala");
1)我会在内存中得到1000次"拉拉"吗?(不使用intern…)
2)"lalala"最终会被取消吗?
3)"拉拉"已经被拘禁了吗?如果是,为什么我需要从池中"得到"它,而不是再写一次"lalala"?
字符串字面值被自动存储(因此,如果代码包含"lalala" 1000次,则只存在一个实例)。
这样的字符串不会被GC化,任何时候它们被引用,引用都将是内部引用。
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语句完成的比较将会快得多。
当然,如果你的文件有可能包含垃圾,那么你不希望这样做,因为加载大量随机字符串到内部池肯定会杀死你的程序的性能,并最终耗尽内存。