String.IsInterned的目的是什么?

Vij*_*dra 12 .net c# string

String课堂上有一种方法IsInterned().我从不使用这种方法.请帮助我了解这种方法的最佳用途.

Jon*_*nna 10

考虑到实习是一种优化; 它会降低一些理想的品质,以增加其他品质.特别是实习具有以下优点:

  1. 内存不会浪费在重复的字符串上.
  2. 两个已知的字符串之间的相等比较非常快.
  3. 恰好被中断的字符串之间的相等比较仍然比没有被中断的字符串快得多.
  4. 在某些情况下,其他比较会获得性能优势.

它具有以下不良品质:

  1. 字符串不是经常收集的垃圾(如果有的话),因此可以回收的内存用于永远不会再看到的字符串,或者很长时间.(实习你所有的字符串,你最终可能会有非常讨厌的内存使用).

作为一种优化,我们使用它来衡量好的品质或者质量不好的地方(如果我们知道字符串将会在应用程序的整个生命周期中出现,或者知道它会多次使用,然后坏部分不成立).

并且出于同样的原因,我们不会使用它,因为坏的品质会超过好处.(大多数时候).

IsInterned() 可以用来找到一个分道点.

考虑我有一个字符串属性Name:

public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

假设我知道查找具有给定对象的对象是常见的Name,或者尝试查找具有相同对象的对象,Name或者对其进行大量的相等比较.或者让我们说我知道会有很多其他具有相同的对象Name.或两者.

在这些情况下,我可能会考虑实习:

private string _name;
public string Name
{
  get { return _name; }
  set { _name = string.Intern(value); }
}
Run Code Online (Sandbox Code Playgroud)

当然,这是否是一个好主意取决于上面提到的实习的好坏.

中间使用和不使用是可能的:

private string _name;
public string Name
{
  get { return _name; }
  set { _name = string.IsInterned(value) ?? value; }
}
Run Code Online (Sandbox Code Playgroud)

如果字符串value已经被实习,那么我们实习的下方已经在工作,我们不再受苦,所以我们利用它.但如果value还没有实习,那么我们只是按原样使用它.

这也是一种优化,可以针对不同的情况进行优化.只有当看到的合理数量的值可能被某些其他代码(或者因为它们与程序集中的文字匹配)有效时,它才会受益,否则它只会浪费时间进行查找.它可能不那么经常有用Intern(),反过来不仅仅使用字符串而忽略实习,但确实显示了它可能有用的时间.


Pet*_*nov 3

一种可能的用途是如果您想锁定字符串值。

在下面的:

string s = //get it from somewhere, e.g. a web request
lock (s){
//do something
}
Run Code Online (Sandbox Code Playgroud)

有一个问题,因为可能有两个不同的请求对同一个字符串,但它们都输入了受保护的代码。这是因为可能有两个不同的字符串对象具有相同的值。

然而,有一个叫做实习池的东西,它是一个包含一些字符串的单个实例的表(例如,所有文字都在那里)。

您可以使用它来使锁定工作:

string s = //get it from somewhere, e.g. a web request
lock (string.Intern(s)){
//do something
}
Run Code Online (Sandbox Code Playgroud)

该函数将返回对实习池中字符串的引用,该字符串与 s 具有相同的值,因此锁定是安全的。

IsIntern函数只是检查您持有的引用是否是对实习池中字符串的引用。

  • 切勿锁定绳子。字符串是域敏捷的,即可以从多个应用程序域访问同一个字符串实例,尤其是在驻留时。结果将是一个线程可能正在等待在不相关的应用程序域中释放锁......这是非常令人讨厌的效果。 (9认同)