string.Empty与""存储及性能对比

首先,看一下String类

一、String类[只展示探讨部分]

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{

 public static readonly string Empty;

static String()
{
    Empty = "";
    return;
}
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public extern String(char[] value);
 

}

实例化某个string对象,有两大种方式,一个需要new String(),一个不需要new,例如:

<1>调用基本构造函数:

【C#】:  string str=new string(new char[]{'a','b','c'});

【IL】:   L_0012: newobj instance void [mscorlib]System.String::.ctor(char[])
<2>直接赋值:

【C#】:string str="abc";

【IL】: L_0018: ldstr “abc”

在<1>中,是很平常的实例化方式,而在<2>中生成的IL代码中并没有出现newobj操作符,但出现了ldstr(推送对元数据中存储的字符串的新对象引用)。关于lbstr这种实例化string的方式,是一种驻留机制,即:字符串值相同的只实例化一次(在内存中分配一次空间),其它相同的只是统一指向第一次分配的空间。每次string str="字符串",都会从字符串驻留池中取,如果有,直接使用原来的,没有则创建新的实例。

 

二、Empty与“”差异分析

 public static readonly string Empty;
       static String()
        {
          Empty = "";
          return;
        }
  所以,当第一次实例化string类时,静态构造函数就初始化Empty,且以后直接获取只读Empty值。
  例如:
  string str=string.Empty;//如果这是第一次使用string类,调用静态构造函数,初始化Empty,在堆中,开辟某一空间,[000001]保存值为“”;
  string str2=string.Empty//这是第二次使用,所以直接从内存读取到并赋值,指向原始空值堆空间[00000001]。
  
  而直接赋值 str="";则会:
  例如:
  string str=“”; //如果是第一次使用string类,(结合上文string类介绍,ldstr)如同普通类,构造函数 string str=new string(char[]{''});在堆中,开辟某一空间,[000001]保存值为“”;
  string str2=""; //这是第二次使用,(结合上文string类介绍,ldstr).NET对string有驻留机制处理,即相同的字符串值,则会继续使用原来堆中的值数据,
                      //当然,这个过程必然会经过一系列的处理,消耗一定的性能!!!

三、分析总结

 <1>在内存分配上:

 string.Empty与“”,没有差别。都是一个系统上,""值对象只有一个!!!

<2>在性能上:

string.Empty高,不需要在驻留机制上做处理。

posted @ 2013-09-06 02:05  阿步GoToDoNet  阅读(345)  评论(3编辑  收藏  举报