c# - 缓存字符串需要担心吗?

标签 c# .net string garbage-collection

我无法找到任何明确回答我的问题的内容,所以我想我会问:这是最佳实践还是只是偏好做类似的事情:

public static class FixedStrings
{
      public static readonly string foo = "bar";
}

class Example1
{
    void UseString()
    {
        Console.WriteLine(FixedStrings.foo);
    }
}

而不是:

class Example2
{
    void UseString()
    {
        Console.WriteLine("bar");
    }
}

这是我目前的理解(我可能是错的):

  1. 这是内存与 GC 分配的权衡;因此,如果经常调用需要字符串的方法,或者该方法处于长时间运行的进程中,则第一个示例是更好的选择。
  2. 如果内存不是问题,缓存可重用的字符串(或任何对象)将减少 GC 花费的时间并提高程序的响应能力。
  3. .NET GC 做得相当不错,但定期有几个字符串会经历几代,尤其是在负载情况下,并且在很长一段时间后可能会导致完全 GC 清理。
  4. Example1节拍Example2几乎总是在性能方面。

我注意到在不同地方的示例代码中,人们都使用这两种方法。我不确定这是否只是因为 example2打字速度更快或者因为阅读偏好。我也很好奇,编译器是否足够聪明,可以自动将其中一些字符串转换为缓存变量?

请记住,我说的所有这些都是我从互联网上学到的,我没有受过正规教育。我的假设example1可能是非常错误的更好

这就是我担心如此小的优化的原因:

在我的实际项目中这并不是那么小;在某些情况下,我可能每秒使用这些字符串数千次。

最佳答案

I am also curious, is the compiler smart enough to automatically turn some of these strings into cached variables?

是的。如果单个程序集中具有相同的字符串文字,作为一种优化,C# 将仅在运行时创建该字符串的一个实例并缓存它。这称为“字符串实习”。 This blog post by Eric Lippert解释了一般原则及其对性能/垃圾收集的影响。

作为字符串驻留的结果,假设这些示例中的所有代码都存在于单个程序集中,您的两个示例都会在运行时只产生一个字符串分配。

因此,您遵循哪种模式是风格问题。对于文档和教育中使用的示例,如果字符串与代码的其余部分“一致”,通常更容易阅读,如示例 2。如果您正在编写一个大型、复杂的程序,必须使用完全相同的字符串在多个地方,我更喜欢示例 1。这可以避免在每个使用字符串的地方重新输入字符串(可能会输入错误),为代码中的字符串提供一个有意义的名称,并且允许您仅编辑一行(如果字符串在未来的版本中需要更改。

最后,关于你提到的项目。如果您关心的字符串是在编译时定义的(即,它们是像 "My String" 这样的字符串文字),那么 C# 的自动字符串驻留可能就足够了。如果您有很多字符串直到运行时才知道,但您希望避免重新分配,您可能需要声明一些东西来保存这些字符串对象以供代码稍后使用。您使用哪种数据结构取决于您的用例。

您还可以通过调用 String.Intern(String) 强制运行时保留字符串。 。此方法将给定的字符串放入字符串驻留缓存中(如果尚不存在)并从缓存中返回该字符串。请注意,您仍然需要以某种方式分配字符串以将其传递到此方法中,但该实例的生命周期可能会短得多,从而使您的项目执行得更好。

关于c# - 缓存字符串需要担心吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55113012/

相关文章:

javascript - anchor 标记上的 JQuery click() 未从 WebBrowser 控件内的注入(inject)脚本触发

c# - 如何在 C# 中获取包含今天日期的文件名

java - 开销与代码速度(java.io.File 数组与 java.lang.String 数组)

c# - 正则表达式卡在某些记录中

c# - 如何在 ASP.NET 中将空字符串设置为 DataSource 参数的默认值?

c# - .NET 的 64 位系统上的原子读/写大小?

c# - 为什么不同的传委托(delegate)方式在性能上会有如此大的差异?

java - url 收割机字符串操作

java分割字符串

c# - AjaxControlToolkit NoBotState 始终为 InvalidBadResponse