String.IsInterned的目的是什么?

时间:2011-06-21 05:01:26

标签: c# .net string

String课程中,有一种方法IsInterned()。我从不使用这种方法。请帮助我理解这种方法的最佳用途。

5 个答案:

答案 0 :(得分:9)

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

  1. 内存不会浪费在重复的字符串上。
  2. 两个已知的字符串之间的平等比较非常快。
  3. 碰巧被拘禁的字符串之间的平等比较仍然比没有实习的情况要快得多。
  4. 在某些情况下,其他比较可以获得性能优势。
  5. 它具有以下不良品质:

    1. 字符串不是经常收集的垃圾(如果有的话),因此可以回收的内存用于从未再次看到过的字符串,或者很长时间。 (实习你的所有字符串,你最终可能会使用非常讨厌的内存)。
    2. 作为一种优化,我们使用它,要么好的品质超重,要么质量不好(如果我们知道字符串将在应用程序的整个生命周期中使用) ,或者知道它将被多次使用,然后坏部分不会持有)。

      出于同样的原因,我们不会使用它,因为糟糕的品质会超过好处。 (大部分时间)。

      IsInterned()可用于查找分数点。

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

      public string Name { get; set; }
      

      让我们说我知道查找具有给定Name的对象或尝试查找具有相同Name的对象或以其他方式做很多事情很常见平等比较。或者说我知道会有很多其他具有相同Name的对象。或两者。

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

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

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

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

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

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

      这也是一种优化,可以针对不同的情况进行优化。只有当看到的合理数量的值可能被某些其他代码(或者因为它们与程序集中的文字匹配)有效时,它才会受益,否则它只会浪费时间进行查找。它可能不如Intern()有用,而kern.ipc.maxsockbuf=4194304 # (default 2097152) net.inet.tcp.sendbuf_max=4194304 # (default 2097152) net.inet.tcp.recvbuf_max=4194304 # (default 2097152) net.inet.tcp.cc.algorithm=htcp # (default newreno) net.inet.tcp.cc.htcp.adaptive_backoff=1 # (default 0 ; disabled) net.inet.tcp.cc.htcp.rtt_scaling=1 # (default 0 ; disabled) net.inet.ip.forwarding=1 # (default 0) net.inet.ip.fastforwarding=1 # (default 0) kern.ipc.soacceptqueue=1024 # (default 128 ; same as kern.ipc.somaxconn) net.inet.tcp.mssdflt=1460 # (default 536) net.inet.tcp.minmss=1300 # (default 216) net.inet.tcp.rfc1323=1 # (default 1) net.inet.tcp.rfc3390=1 # (default 1) net.inet.tcp.sack.enable=1 # (default 1) net.inet.tcp.tso=0 # (default 1) net.inet.tcp.nolocaltimewait=1 # (default 0) net.inet.tcp.experimental.initcwnd10=1 # (default 1 for FreeBSD 10.1) net.inet.tcp.syncache.rexmtlimit=0 # (default 3) net.inet.ip.rtexpire=2 # (default 3600) net.inet.ip.rtminexpire=2 # (default 10 ) net.inet.tcp.syncookies=0 # (default 1) net.inet.ip.check_interface=1 # verify packet arrives on correct interface (default 0) net.inet.ip.process_options=0 # ignore IP options in the incoming packets (default 1) net.inet.ip.redirect=0 # do not send IP redirects (default 1) net.inet.ip.stealth=1 # do not reduce the TTL by one(1) when a packets goes through the firewall (default 0) net.inet.icmp.drop_redirect=1 # no redirected ICMP packets (default 0) net.inet.tcp.drop_synfin=1 # SYN/FIN packets get dropped on initial connection (default 0) net.inet.tcp.fast_finwait2_recycle=1 # recycle FIN/WAIT states quickly (helps against DoS, but may cause false RST) (default 0) net.inet.tcp.icmp_may_rst=0 # icmp may not send RST to avoid spoofed icmp/udp floods (default 1) net.inet.tcp.msl=5000 # 5s maximum segment life waiting for an ACK in reply to a SYN-ACK or FIN-ACK (default 30000) net.inet.tcp.path_mtu_discovery=0 # disable MTU discovery since most ICMP type 3 packets are dropped by others (default 1) net.inet.udp.blackhole=1 # drop udp packets destined for closed sockets (default 0) net.inet.tcp.blackhole=2 # drop tcp packets destined for closed ports (default 0) security.bsd.see_other_uids=0 # users only see their own processes. root can see all (default 1) 反过来不仅仅是使用字符串而忽略实习,但确实显示了它可能有用的时间。

答案 1 :(得分:3)

如果你想锁定字符串值,可能会有一种用途。

以下内容:

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

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

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

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

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

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

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

答案 2 :(得分:2)

请参阅Eric的帖子,我认为这是实习生解释的最佳位置

答案 3 :(得分:1)

C#中的字符串文字是实习的(也就是说,它们存储在实习池中) 对于文字的每次出现,只有一个实例。如果你自己做 语言(例如某些脚本系统),您可以使用IsInterned和Intern来产生 同样的事情。

答案 4 :(得分:0)

看看this。实际上该线程中有一个用例。