string str="";
str="abc";
和
string str="abc";
和
string str=new string ("abc");
哪一个效率高点,为什么?
str="abc";
和
string str="abc";
和
string str=new string ("abc");
哪一个效率高点,为什么?
解决方案 »
- 求一个正则表达式:去除文件后缀名(如:.jpg .jpeg .png)
- 界面中的问题
- 怎样反射生成数组
- DataGridView怎么弄个标题出来?
- 怎么在MainMenu中显示ToolTip的提示??????????
- FileOpenDialog()
- 水晶报表 搞了好几天搞不出来,高手请进帮忙解决!如能解决,分数再加++++++++
- 多线程操作EXCEL问题求教
- 我做一个控件 UserContorl,我想使它具有boderStyle 属性(none,fixedSingle,fixed3d,) 如何实现?
- 讨论一下用C#(ASP.NET)和.NET 架构 做多层模型的WEB 应用的效率?
- 正则表达式的问题,都来拿分啊
- SQL存储过程的一点小问题
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"),因为如果有重复的字符串时,第一种方式可以节省空间。
str="abc";
和
string str="abc";
以上两种的效率一样,因为""和"abc"都是在字符串池中的,只是修改str指向的引用。效率差别是不存在的。string str=new string ("abc");
这句应该是错误的,解释不通。
string str=new string ({'a','b','c'});
这样可以,但创建数组引用类型,是会消耗时间的。
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
错。首先,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行。结果很明显了吧? 第二种初始化方式效率最高。
------------------------------
写法是错误的,同时与另外两种 没有直接可比性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 来将字符串驻留在字符池中
这句是错的,应是 il 使用 newarr char 来创建string str = new string('a', 3);这个是使用 newobj 来实例化对象
2. 其实在在java中有一个“字符数据池”的内存管理机制。
3. String str="abc",执行这句话时,会先去“字符数据池”搜索时候有“abc”这个字符串,如果有,则将字符串的首地址赋值给str,如果没有,生成一……
应该是这个吧
在java里面肯定第二种效率高,
在C#里面没有可比性.性能差不多.
循环1000次以后就可以看出来了.
个人认为,第二种方法的效率高一点。可以简单的认为第一种方法调用了两次赋值函数,第二种方法只调用了一赋值函数,而第三种方法先调用一次拷贝构造函数,再调用一次赋值函数
其实这三种方法的效率差不多,只是第一种方法的string str="";有点显得多余,定义后立刻赋是一个好习惯。如果不是非常非常频繁地调用,这些差异是可以忽略的。
当然了,这是我类比C++,依样画葫芦。若有不对的地方,请指正,谢谢!
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 所以就这两句效率是一样的,无所谓可比性!!
效率不太清楚,但是如果你有2个abc的话,我觉得还是用第一个好,因为同样的对象编译器会优化,而重新new的对象,编译器是不能优化的!