开发者

What is the purpose of String.IsInterned?

In the String class there is a method IsInterned(). I nev开发者_运维知识库er use this method. Please help me to understand the best uses of this method.


Consider that interning is an optimisation; it trades a decrease in some desirable qualities for an increase in others. In particular interning has the following good qualities:

  1. Memory is not wasted on duplicate strings.
  2. Equality comparison between strings known to both be interned is extremely fast.
  3. Equality comparison between strings that happen to be interned is still much faster than if they aren't interned.
  4. Other comparisons get a performance benefit in some cases.

It has the following bad qualities:

  1. Strings are not garbage collected as often (if at all), so memory that could be reclaimed is used on strings that are never seen again, or for a very long time. (Intern all your strings and you could end up with really nasty memory use).

As an optimisation, we use it where the either the good qualities out-weigh the bad or where the bad qualities don't hold (if we know the string is going to be around for the lifetime of the application anyway, or know it will be used many times, then the bad part doesn't hold).

And by the same token we don't use it where the bad qualities will out-weigh the good. (Most of the time).

IsInterned() can be used to find a part-way point.

Consider I have a string property Name:

public string Name { get; set; }

Let's say I know that it's common to look for objects with a given Name, or to try to find objects with the same Name or otherwise do a lot of equality comparisons on it. OR Let's say I know there will be a lot of other objects with the same Name. OR Both.

In these cases I might consider interning:

private string _name;
public string Name
{
  get { return _name; }
  set { _name = string.Intern(value); }
}

Of course, whether this was a good idea or not depends on the good and bad qualities of interning mentioned above.

In-between using and not using is the possibility:

private string _name;
public string Name
{
  get { return _name; }
  set { _name = string.IsInterned(value) ?? value; }
}

Here if the string value is already interned then we the down-sides of interning are already at work and we don't suffer any more, so we take advantage of it. But if value is not already interned then we just use it as-is.

This is also an optimisation, that optimises for a different case. It only benefits if a reasonable number of the values seen are likely to be interned by some other code (or because they match literals in the assembly), otherwise it just wastes time doing lookups. It's probably less often useful than Intern() which in turn is less often useful than just using the strings and ignoring interning, but that does show a time when it could be useful.


One possible use would be if you want to lock on the string value.

In the following:

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

there is a problem, because there might be two different requests for the same string, but they both enter the protected code. This is because there might be two different string objects that has the same value.

However there is something called intern pool, which is a table that contains a single instance of some strings (all the literals are there for example).

You can use it to make the locking work:

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

This function would return a reference to a string in the intern pool, which has the same value as s, so is safe for locking.

The IsIntern function simply checks whether the reference you are holding is a reference to a string on the intern pool.


String literals in C# are interned (that is, they are stored into an intern pool) so that for each occurrence of the literal there is only one instance. If you are making your own language (for example some script system), you can use IsInterned and Intern to yield the same thing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜