gpt4 book ai didi

C#:具有相同内容的字符串

转载 作者:可可西里 更新时间:2023-11-01 03:05:57 26 4
gpt4 key购买 nike

我听说和读到一个字符串不能改变(不可变的?)。我想那应该是正确的。但我也听说两个内容相同的字符串共享相同的内存空间(或你所说的)。这是正确的吗?

如果是这样,这是否意味着如果我创建一个包含数千个字符串的列表,如果其中大多数字符串彼此相等,它实际上根本不会占用太多空间?

最佳答案

编辑:在下面的回答中,我将实习生池称为特定于 AppDomain 的;我很确定这就是我之前观察到的,但是 String.Intern 的 MSDN 文档建议整个过程只有一个实习生池,这使这一点变得更加重要。

原始答案

(我本来打算将其添加为评论,但我认为这是一个足够重要的点,需要一个额外的答案......)

正如其他人所解释的那样,字符串驻留发生在所有字符串文字上,但不会发生在“动态创建”的字符串上(例如,从数据库或文件中读取的字符串,或者使用 StringBuilderString.Format 构建的字符串。)

但是,我不会建议调用 String.Intern绕过后一点:它将在你的 AppDomain 的生命周期内填充实习生池 。相反,使用仅供您使用的本地池。这是此类池的示例:

public class StringPool
{
private readonly Dictionary<string,string> contents =
new Dictionary<string,string>();

public string Add(string item)
{
string ret;
if (!contents.TryGetValue(item, out ret))
{
contents[item] = item;
ret = item;
}
return ret;
}
}

然后你只需使用类似的东西:

string data = pool.Add(ReadItemFromDatabase());

(请注意,池不是线程安全的;正常使用不需要它。)

这样一来,您就可以在不再需要时立即丢弃您的池,而不是永远在内存中保留大量潜在的字符串。你也可以让它更聪明,实现 LRU 缓存或者如果你真的想要的话。

编辑:只是为了阐明为什么这比使用 String.Intern 更好... 假设您从数据库或日志文件中读取了一堆字符串,对其进行处理,然后转到另一项任务。如果您调用 String.Intern在这些字符串上,只要您的 AppDomain 存在,它们永远不会被垃圾回收还活着-甚至可能还活着。如果您加载多个不同的日志文件,您将在您的实习生池中逐渐积累字符串,直到您完成或耗尽内存。相反,我建议采用这样的模式:

void ProcessLogFile(string file)
{
StringPool pool = new StringPool();
// Process the log file using strings in the pool
} // The pool can now be garbage collected

在这里,您可以获得同一个文件中的多个字符串在内存中只存在一次的好处(或者至少,只超过 gen0 一次),但您不会污染“全局”资源(实习生池)。

关于C#:具有相同内容的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/555871/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com