社区
C#
帖子详情
今天发现C#的字符串操作是优化过的~~~
Lostinet
2002-12-17 08:19:02
例如:
string a=str1+str2+str3+str4;
将会变成:
string a=String.Concat(str1,str2,str3,str4);
来编译~~~
...全文
178
30
打赏
收藏
今天发现C#的字符串操作是优化过的~~~
例如: string a=str1+str2+str3+str4; 将会变成: string a=String.Concat(str1,str2,str3,str4); 来编译~~~
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
30 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
smilefox
2002-12-19
打赏
举报
回复
www.compuware.com
www.compuware-china.com
Compuware Numega Devpartner
Numega的东西应该知道吧,softice,boudschecker。。。。。
smilefox
2002-12-19
打赏
举报
回复
佛说:
一切众生皆有如来智慧德相,
皆因妄想执著而不能证得。
佛还说:大家该睡觉了。
7710703
2002-12-19
打赏
举报
回复
呵呵,不好意思,
smilefox(笑面狐):
能否告知一下你是在哪里搞到的Compuware Devpartner?
谢谢。
smilefox
2002-12-19
打赏
举报
回复
我也上床了,一个人。
dy_2000_abc
2002-12-19
打赏
举报
回复
柴门闻犬吠,风雪夜归人。同路同路
Lostinet
2002-12-19
打赏
举报
回复
在循环中,Contact很难用的。
所以我一般也是用StringBuilder
我睡了。
smilefox
2002-12-19
打赏
举报
回复
都是夜猫子。
dy_2000_abc
2002-12-19
打赏
举报
回复
不能吧,我觉得如果字符数是固定的话,StringBuilder怎么也不可能比Concat快,因为Concat一次就将内存分配完毕,而StringBuilder如果初次分配的内存不够的话,还要再次分配内存。可这没有太大的意义了,不是太极端(比如:StringBuilder s=new StringBuilder(1))的话,差别是可以忽略的。
smilefox
2002-12-19
打赏
举报
回复
看错了,qqchen79(知秋一叶)说得没错,眼花了。
双眼通红,;-(
smilefox
2002-12-19
打赏
举报
回复
继续讨论:
对qqchen79(知秋一叶)的如下看法,fox不敢苟同-----
">> 关于优化的说法,我个人认为主要是针对第一个例子。而编译器为string >> 其他类型 调用Concat方法的好处在于string + 值类型 这样的情况:
>> string s="a";
>> int n=1;
>> string s1=s+1;
>> 这时,值类型不用装箱了。
应该还是要装箱的,Concat有两种形式,一是接受string,一是object;C#编译器不能随便把int32转成string,只能当object,所以要装箱。如果要优化,用string s1=s+1.ToString()要好一点——这个不用装箱。"
string s="a";
int n=1;
string s1=s+1;其实这里有一个隐含的装箱的过程。
大家要注意一下,
-------------------------
每个值类型都有一个对应的隐含的引用类型,他是在值类型转换为引用类型时自动创建。不是通常的装箱。
看下面的代码:
using System;
namespace box1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
string s1="1";
string s2="2";
string s3="3";
string s=s1+s2+s3;
string d=s+1;//这里有一个隐含的装箱
Console.WriteLine(s);
Console.WriteLine(d);
}
}
}
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 55 (0x37)
.maxstack 3
.locals init ([0] string s1,
[1] string s2,
[2] string s3,
[3] string s,
[4] string d)
IL_0000: ldstr "1"
IL_0005: stloc.0
IL_0006: ldstr "2"
IL_000b: stloc.1
IL_000c: ldstr "3"
IL_0011: stloc.2
IL_0012: ldloc.0
IL_0013: ldloc.1
IL_0014: ldloc.2
IL_0015: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_001a: stloc.3
IL_001b: ldloc.3
IL_001c: ldc.i4.1
IL_001d: box [mscorlib]System.Int32
IL_0022: call string [mscorlib]System.String::Concat(object,
object)
IL_0027: stloc.s d
IL_0029: ldloc.3
IL_002a: call void [mscorlib]System.Console::WriteLine(string)
IL_002f: ldloc.s d
IL_0031: call void [mscorlib]System.Console::WriteLine(string)
IL_0036: ret
} // end of method Class1::Main
隐含的装箱在这里------------------------------
IL_001c: ldc.i4.1
IL_001d: box [mscorlib]System.Int32
IL_0022: call string [mscorlib]System.String::Concat(object,
。。。。
smilefox
2002-12-19
打赏
举报
回复
又有人熬通宵;-),累啊
chinchy
2002-12-19
打赏
举报
回复
拉
qqchen79
2002-12-19
打赏
举报
回复
我还没睡。:)
>> 使用
>> string a=str1+str2+str3+str4
>> 和
>> string a=str1;
>> a+=str2;
>> a+=str3;
>> a+=str4;
这两个不一样,不光是因为Concat函数调用的次数,而且是临时对象的产生:头一个除了str1234以外没有生成多余的临时对象,而后一个每走一步就丢下一个临时对象交给GC收拾(string是immutable的,a+=b相当于string temp = a + b; a = temp;原先的a就没用了)内存的footprint很不光彩。
>> 关于优化的说法,我个人认为主要是针对第一个例子。而编译器为string >> 其他类型 调用Concat方法的好处在于string + 值类型 这样的情况:
>> string s="a";
>> int n=1;
>> string s1=s+1;
>> 这时,值类型不用装箱了。
应该还是要装箱的,Concat有两种形式,一是接受string,一是object;C#编译器不能随便把int32转成string,只能当object,所以要装箱。如果要优化,用string s1=s+1.ToString()要好一点——这个不用装箱。
dy_2000_abc
2002-12-19
打赏
举报
回复
知秋是对的,我写那段的时候,感觉是Concat将会象WriteLine一样,不用装箱了。看样子不能过过分依赖感觉,今天我看了一下Concat的所有重载方法,统统需要引用类型作为参数,也就是说值类型需要先装箱。
smilefox
2002-12-19
打赏
举报
回复
刚刚用Devpartner测了一下:
string s=s1+s2+s3;//执行时间1.2819毫秒
string d=s+1;//这里有一个隐含的装箱
执行时间61.0279毫秒
看来装箱操作对性能影响较为明显。
机器配置:PIII650 256M DELL Latitude笔记本电脑
lixigang
2002-12-18
打赏
举报
回复
真长见识
Lostinet
2002-12-18
打赏
举报
回复
chenbinghui(阿炳):
StringBuilder是快,但只有极少应用是才是100倍或以上。
static public string String::Contact(...)是最快的。
smilefox
2002-12-18
打赏
举报
回复
谢谢dy_2000_abc(芝麻开门) Lostinet(迷失网络) 两位的精彩解说。
楼主的例子确实没问题--------------------
"例如:
string a=str1+str2+str3+str4;
将会变成:
string a=String.Concat(str1,str2,str3,str4);
来编译~~~" -----------------------
可能大家误认为str1~4不是常量字符串"111","222",....
而是string str1="1111"......
string str4+=..诸如此类,这样的话就会是垃圾了。
dy_2000_abc(芝麻开门)代码已经说明了问题,看来我有一点说错了。
说到垃圾代码,刚学C#时我经常写那种代码。我想这是每个程序员的成长过程中肯定会经历的,不管他是用C/C++/C#/Delphi,还是Java/VB/ASM等等。关键在于能不断的研究和实践,这一点很佩服dy_2000_abc(芝麻开门)兄,向你学习!;-)
Lostinet
2002-12-18
打赏
举报
回复
楼上的,你的例子太极端了.
统计应该是这样做的:
当然可以指定StringBuilder的capacity,这样可以快1/5左右。
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
namespace L
{
public class L
{
static void Test0()
{
DateTime dt1=DateTime.Now;
for(int count=0;count<666666;count++)
{
string str1="a";
string str2="b";
string str3="c";
string str4="d";
string res=str1+str2+str3+str4;
}
DateTime dt2=DateTime.Now;
Console.WriteLine( (dt2-dt1).TotalMilliseconds );
}
static void Test1()
{
DateTime dt1=DateTime.Now;
for(int count=0;count<666666;count++)
{
string[] strs=new string[4];
for(int i=0;i<4;i++)
{
strs[i]="a";
}
string res=String.Concat(strs);
}
DateTime dt2=DateTime.Now;
Console.WriteLine( (dt2-dt1).TotalMilliseconds );
}
static void Test2()
{
DateTime dt1=DateTime.Now;
for(int count=0;count<666666;count++)
{
StringBuilder sb=new StringBuilder();
for(int i=0;i<4;i++)
{
sb.Append("a");
}
string res=sb.ToString();
}
DateTime dt2=DateTime.Now;
Console.WriteLine( (dt2-dt1).TotalMilliseconds );
}
static void Main()
{
Test0();
Console.WriteLine();
Test1();
Console.WriteLine();
Test2();
}
}
}
dy_2000_abc
2002-12-18
打赏
举报
回复
漏了一段代码
using System;
namespace abc
{
public class a
{
static void Main()
{
string s1="1";
string s2="2";
string s3="3";
string s4="3";
string s5="3";
string s6="3";
string s7="3";
string s=s1+s2+s3+s4+s5+s6+s7;
Console.WriteLine(s);
}
}
}
上面代码的IL如下:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 108 (0x6c)
.maxstack 3
.locals init (string V_0,
string V_1,
string V_2,
string V_3,
string V_4,
string V_5,
string V_6,
string V_7,
string[] V_8)
IL_0000: ldstr "1"
IL_0005: stloc.0
IL_0006: ldstr "2"
IL_000b: stloc.1
IL_000c: ldstr "3"
IL_0011: stloc.2
IL_0012: ldstr "3"
IL_0017: stloc.3
IL_0018: ldstr "3"
IL_001d: stloc.s V_4
IL_001f: ldstr "3"
IL_0024: stloc.s V_5
IL_0026: ldstr "3"
IL_002b: stloc.s V_6
IL_002d: ldc.i4.7
IL_002e: newarr [mscorlib]System.String
IL_0033: stloc.s V_8
IL_0035: ldloc.s V_8
IL_0037: ldc.i4.0
IL_0038: ldloc.0
IL_0039: stelem.ref
IL_003a: ldloc.s V_8
IL_003c: ldc.i4.1
IL_003d: ldloc.1
IL_003e: stelem.ref
IL_003f: ldloc.s V_8
IL_0041: ldc.i4.2
IL_0042: ldloc.2
IL_0043: stelem.ref
IL_0044: ldloc.s V_8
IL_0046: ldc.i4.3
IL_0047: ldloc.3
IL_0048: stelem.ref
IL_0049: ldloc.s V_8
IL_004b: ldc.i4.4
IL_004c: ldloc.s V_4
IL_004e: stelem.ref
IL_004f: ldloc.s V_8
IL_0051: ldc.i4.5
IL_0052: ldloc.s V_5
IL_0054: stelem.ref
IL_0055: ldloc.s V_8
IL_0057: ldc.i4.6
IL_0058: ldloc.s V_6
IL_005a: stelem.ref
IL_005b: ldloc.s V_8
IL_005d: call string [mscorlib]System.String::Concat(string[])
IL_0062: stloc.s V_7
IL_0064: ldloc.s V_7
IL_0066: call void [mscorlib]System.Console::WriteLine(string)
IL_006b: ret
} // end of method a::Main
代码好像很多,其实意思很简单
加载更多回复(10)
C#
文件系统的
操作
本课程将介绍如何在
C#
中执行读写文件
操作
,读写文件夹
操作
。
C#
字符串
操作
——性能
优化
细节
1、使用string.Empty给一个空
字符串
变量赋初始值 String.Empty是一个指代,而””是具体的实现 1、使用string.Empty给一个空
字符串
变量赋初始值 String.Empty是一个指代,而””是具体的实现 [csharp] view ...
C#
字符串
操作
:拼接、截取、分割等高效处理方法
在
C#
编程中,
字符串
操作
是不可避免的一部分。无论是拼接多个
字符串
,还是截取子
字符串
,抑或是按照特定规则进行分割,都需要对
字符串
进行处理。本篇博客将介绍一些在
C#
中高效处理
字符串
的方法,包括拼接、截取、分割...
C#
性能
优化
——三种
字符串
拼接效率
C#
性能
优化
——三种
字符串
拼接效率
字符串
拼接主要包括三类:+,String.Format(),StringBuilder.Append() 1)对于少量固定的
字符串
拼接,如string s= "a" + "b" + "c",系统会
优化
成s= String.Concat("a",...
C#
字符串
比较
优化
(StringComparison)
因朋友极力推荐,近一年在一家国企上班。忙忙碌碌天天叨叨不停,就是不写代码。现在之前的基础都忘差不多了,不感慨...我们在写程序的时候,经常会用到
字符串
对比。例如:if(IsCheck =="true") 当大小写敏感的时候一
C#
110,545
社区成员
642,580
社区内容
发帖
与我相关
我的任务
C#
.NET技术 C#
复制链接
扫一扫
分享
社区描述
.NET技术 C#
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
让您成为最强悍的C#开发者
试试用AI创作助手写篇文章吧
+ 用AI写文章