Jam*_*ead 12 c# compiler-construction string concatenation
我的三个同事告诉我,没有理由使用StringBuilder来代替使用+运算符的连接.换句话说,这对一堆字符串很好:myString1 + myString2 + myString3 + myString4 + mySt...
他们使用的基本原理是,从.NET 2开始,如果使用+运算符,C#编译器将构建相同的IL,就像使用StringBuilder一样.
这对我来说是新闻.他们是对的吗?
Jef*_*tes 25
不,他们不正确.字符串连接创建一个新的,string而StringBuilder使用一个可变大小的缓冲区来构建字符串,只在string调用时创建一个对象ToString().
如果您想进一步阅读有关该主题的内容,那么在互联网上有很多关于字符串连接技术的讨论.大多数注意力集中在循环中使用时不同方法的效率.在这种情况下,StringBuilder使用字符串运算符进行字符串连接比10个或更多字符串的连接更快,这应该表明它必须使用与连接不同的方法.
也就是说,如果你连接常量字符串值,字符串运算符会更好,因为编译器会将它们分解,如果执行非循环连接,使用运算符会更好,因为它们应该导致单个调用string.Concat.
Dar*_*rov 16
不,他们不正确,它不会产生相同的IL:
static string StringBuilder()
{
var s1 = "s1";
var s2 = "s2";
var s3 = "s3";
var s4 = "s4";
var sb = new StringBuilder();
sb.Append(s1).Append(s2).Append(s3).Append(s4);
return sb.ToString();
}
static string Concat()
{
var s1 = "s1";
var s2 = "s2";
var s3 = "s3";
var s4 = "s4";
return s1 + s2 + s3 + s4;
}
Run Code Online (Sandbox Code Playgroud)
IL的StringBuilder:
.method private hidebysig static string StringBuilder() cil managed
{
.maxstack 2
.locals init (
[0] string s1,
[1] string s2,
[2] string s3,
[3] string s4,
[4] class [mscorlib]System.Text.StringBuilder sb)
L_0000: ldstr "s1"
L_0005: stloc.0
L_0006: ldstr "s2"
L_000b: stloc.1
L_000c: ldstr "s3"
L_0011: stloc.2
L_0012: ldstr "s4"
L_0017: stloc.3
L_0018: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_001d: stloc.s sb
L_001f: ldloc.s sb
L_0021: ldloc.0
L_0022: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0027: ldloc.1
L_0028: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_002d: ldloc.2
L_002e: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0033: ldloc.3
L_0034: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0039: pop
L_003a: ldloc.s sb
L_003c: callvirt instance string [mscorlib]System.Object::ToString()
L_0041: ret
}
Run Code Online (Sandbox Code Playgroud)
IL of Concat:
.method private hidebysig static string Concat() cil managed
{
.maxstack 4
.locals init (
[0] string s1,
[1] string s2,
[2] string s3,
[3] string s4)
L_0000: ldstr "s1"
L_0005: stloc.0
L_0006: ldstr "s2"
L_000b: stloc.1
L_000c: ldstr "s3"
L_0011: stloc.2
L_0012: ldstr "s4"
L_0017: stloc.3
L_0018: ldloc.0
L_0019: ldloc.1
L_001a: ldloc.2
L_001b: ldloc.3
L_001c: call string [mscorlib]System.String::Concat(string, string, string, string)
L_0021: ret
}
Run Code Online (Sandbox Code Playgroud)
你也可能会觉得这篇文章很有趣.
不,他们不是.他们肯定产生不同的IL.它使用不同的调用:String.Concat在非StringBuilder情况下.
String.Concat调用一个名为的私有方法ConcatArray,它只分配一个新字符串,足以保存最终结果.所以,非常不同,但这并不意味着使用+运算符连接的效率低于使用StringBuilder.事实上,它几乎肯定更有效率.此外,在连接常量的情况下,它在编译时完成.
但是,当您在循环中进行连接时,编译器无法执行此类优化.在这种情况下,StringBuilder对于相当长的字符串使用会更好.
| 归档时间: |
|
| 查看次数: |
3074 次 |
| 最近记录: |