string str="";
str="abc";

string str="abc";

string str=new string ("abc");
哪一个效率高点,为什么?

解决方案 »

  1.   

     1. String str=new String("abc")和String str="abc"的字符串“abc”都是存放在堆中,而不是存在栈中。
     2. 其实在在java中有一个“字符数据池”的内存管理机制。
     3. String str="abc",执行这句话时,会先去“字符数据池”搜索时候有“abc”这个字符串,如果有,则将字符串的首地址赋值给str,如果没有,生成一个新的字符串“abc”并且将首地址赋值给str;
     4. String str=new String("abc"),执行这句话时,不会考虑时候已经存在了“abc”这个字符串,而是直接生成一个新的字符串“abc”并将首地址赋值给str,注意“abc”并不放在“字符数据池”中;
     5. 由以上分析可知,String str="abc"和效率要高于String str=new String("abc"),因为如果有重复的字符串时,第一种方式可以节省空间。
      

  2.   

    string str="";
    str="abc";

    string str="abc";
    以上两种的效率一样,因为""和"abc"都是在字符串池中的,只是修改str指向的引用。效率差别是不存在的。string str=new string ("abc");
    这句应该是错误的,解释不通。
    string str=new string ({'a','b','c'});
    这样可以,但创建数组引用类型,是会消耗时间的。
      

  3.   


    12 楼正解 附上 IL
      .locals init ([0] string test,
               [1] string test1)
      IL_0000:  nop
      IL_0001:  ldstr      ""
      IL_0006:  stloc.0
      IL_0007:  ldstr      "abc"
      IL_000c:  stloc.0
      IL_000d:  ldstr      "abc"
      IL_0012:  stloc.1
      IL_0013:  ret
      

  4.   


    错。首先,C#里string类是没有string(string)这样的构造函数的。接近的是string(char[])。
    分析这个问题最好的方式是写一个程序出来,然后用Reflector查看IL.程序
    ==========================================
    01 using ....
    02 namespace StringEfficiency
    03 {
    04    class Program
    05    {
    06        static void Main(string[] args)
    07        {
    08            string str1 = "";
    09            str1 = "abc";
    10            string str2 = "abc";
    11            string str3 = new string(new char[] {'a', 'b','c'});
    12
    13            GC.KeepAlive(str1);
    14            GC.KeepAlive(str2);
    15            GC.KeepAlive(str3);
    16        }
    17    }
    18 }Debug版的IL
    ==========================================
    .method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 3
        .locals init (
            [0] string str1,
            [1] string str2,
            [2] string str3)
        L_0000: nop 
        L_0001: ldstr ""
        L_0006: stloc.0 
        L_0007: ldstr "abc"
        L_000c: stloc.0 
        L_000d: ldstr "abc"
        L_0012: stloc.1 
        L_0013: ldc.i4.3 
        L_0014: newarr char
        L_0019: dup 
        L_001a: ldtoken valuetype <PrivateImplementationDetails>{FDB0FDCE-8477-4DA3-808A-43C5A67EB98A}/__StaticArrayInitTypeSize=6 <PrivateImplementationDetails>{FDB0FDCE-8477-4DA3-808A-43C5A67EB98A}::$$method0x6000001-1
        L_001f: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
        L_0024: newobj instance void [mscorlib]System.String::.ctor(char[])
        L_0029: stloc.2 
        L_002a: ldloc.0 
        L_002b: call void [mscorlib]System.GC::KeepAlive(object)
        L_0030: nop 
        L_0031: ldloc.1 
        L_0032: call void [mscorlib]System.GC::KeepAlive(object)
        L_0037: nop 
        L_0038: ldloc.2 
        L_0039: call void [mscorlib]System.GC::KeepAlive(object)
        L_003e: nop 
        L_003f: ret 
    }Release版的IL:
    ==========================================
    .method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 3
        .locals init (
            [0] string str1,
            [1] string str2,
            [2] string str3)
        L_0000: ldstr ""
        L_0005: stloc.0 
        L_0006: ldstr "abc"
        L_000b: stloc.0 
        L_000c: ldstr "abc"
        L_0011: stloc.1 
        L_0012: ldc.i4.3 
        L_0013: newarr char
        L_0018: dup 
        L_0019: ldtoken valuetype <PrivateImplementationDetails>{D9B06B8D-11D9-4066-B5D7-D772E40F4AB9}/__StaticArrayInitTypeSize=6 <PrivateImplementationDetails>{D9B06B8D-11D9-4066-B5D7-D772E40F4AB9}::$$method0x6000001-1
        L_001e: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
        L_0023: newobj instance void [mscorlib]System.String::.ctor(char[])
        L_0028: stloc.2 
        L_0029: ldloc.0 
        L_002a: call void [mscorlib]System.GC::KeepAlive(object)
        L_002f: ldloc.1 
        L_0030: call void [mscorlib]System.GC::KeepAlive(object)
        L_0035: ldloc.2 
        L_0036: call void [mscorlib]System.GC::KeepAlive(object)
        L_003b: ret 
    }可以看到,Debug版的IL除了加入nop指令以支持语句级别的断点外,其他的IL和Release版是一样的。
    以Release的IL分析:
    L_0000 ~ L_000b (12字节) 对应C#程序的第08 ~ 09行。
    L_000c ~ L_0011 (6字节)对应C#程序的第10行。
    L_0012 ~ L_0028 (22字节)对应C#程序的第11行。结果很明显了吧? 第二种初始化方式效率最高。
      

  5.   

    string str=new string ("abc");
    ------------------------------
    写法是错误的,同时与另外两种 没有直接可比性string str="";
    str="abc";

    string str="abc";这两个有可比性
    ------------------------string str="";
    str="abc";会请求字符池中的 "" ,没有的话创建并返回。然后请求字符池中的 "abc" ,没有的话创建并返回,然后改变 str 的指向。string str="abc";仅仅只是请求字符池中的 "abc" ,没有的话创建并返回给str。而string str = new String(new char[] { 'a', 'b', 'c' });il 则是 使用 newobj 来实例化对象,没有涉及到字符池在字符池中没有 "abc"需要使用 string.Intern 来将字符串驻留在字符池中
      

  6.   


    这句是错的,应是 il 使用 newarr char 来创建string str = new string('a', 3);这个是使用 newobj 来实例化对象
      

  7.   

    1. String str=new String("abc")和String str="abc"的字符串“abc”都是存放在堆中,而不是存在栈中。
    2. 其实在在java中有一个“字符数据池”的内存管理机制。
    3. String str="abc",执行这句话时,会先去“字符数据池”搜索时候有“abc”这个字符串,如果有,则将字符串的首地址赋值给str,如果没有,生成一……
    应该是这个吧
      

  8.   

    明明说的是C#,又拿java里面的语法.
    在java里面肯定第二种效率高,
    在C#里面没有可比性.性能差不多.
    循环1000次以后就可以看出来了.
      

  9.   

        这是C#的代码吧
        个人认为,第二种方法的效率高一点。可以简单的认为第一种方法调用了两次赋值函数,第二种方法只调用了一赋值函数,而第三种方法先调用一次拷贝构造函数,再调用一次赋值函数
        其实这三种方法的效率差不多,只是第一种方法的string str="";有点显得多余,定义后立刻赋是一个好习惯。如果不是非常非常频繁地调用,这些差异是可以忽略的。
        当然了,这是我类比C++,依样画葫芦。若有不对的地方,请指正,谢谢!
      

  10.   

    第二种高,第一种,是先创建字符串"",之后又创建"abc"的,而第二种是直接创建"abc"
      

  11.   

    如果这样写,string s;s="abc",和string s="abc"是一样的
      

  12.   

    纯粹是好奇!分别反编译了一下,
    string str="";
    str="abc";

    string str="abc";以上的IL是一样的,都是
        .entrypoint
        .maxstack 1
        .locals init (
            [0] string str)
        L_0000: nop 
        L_0001: ldstr "abc"
        L_0006: stloc.0 
        L_0007: ret 所以就这两句效率是一样的,无所谓可比性!!
      

  13.   


    效率不太清楚,但是如果你有2个abc的话,我觉得还是用第一个好,因为同样的对象编译器会优化,而重新new的对象,编译器是不能优化的!