例如,编译器是否知道翻译
string s = "test " + "this " + "function";
到
string s = "test this function";
从而避免字符串连接的性能损失?
答案 0 :(得分:46)
是。这是由C#规范保证的。它在7.18节(C#3.0规范)中:
每当表达式满足时 上面列出的要求, 表达式在 编译时间。即使是这样也是如此 表达式是a的子表达式 包含更大的表达式 非常数构造。
(“上面列出的要求”包括应用于两个常量表达式的+运算符。)
答案 1 :(得分:21)
只是关于相关主题的旁注 - C#编译器还将使用“+
”运算符“优化”涉及非文字的多个连接,以单次调用String的多参数重载。 Concat()方法。
所以
string result = x + y + z;
编译为等同于
的东西string result = String.Concat( x, y, z);
而不是更天真的可能性:
string result = String.Concat( String.Concat( x, y), z);
没有什么是惊天动地的,但只想将这一点添加到关于字符串文字级联优化的讨论中。我不知道这种行为是否是语言标准规定的。
答案 2 :(得分:7)
是
C#不仅优化了字符串文字的连接,还将等效的字符串文字折叠为常量,并使用指针引用对同一常量的所有引用。
答案 3 :(得分:5)
是 - 您可以使用ILDASM明确地看到这一点。
示例:
这是一个与您的示例类似的程序,后跟编译的CIL代码:
注意:我正在使用String.Concat()函数来查看编译器如何处理两种不同的连接方法。
<强>程序强>
class Program
{
static void Main(string[] args)
{
string s = "test " + "this " + "function";
string ss = String.Concat("test", "this", "function");
}
}
<强> ILDASM 强>
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 29 (0x1d)
.maxstack 3
.locals init (string V_0,
string V_1)
IL_0000: nop
IL_0001: ldstr "test this function"
IL_0006: stloc.0
IL_0007: ldstr "test"
IL_000c: ldstr "this"
IL_0011: ldstr "function"
IL_0016: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_001b: stloc.1
IL_001c: ret
} // end of method Program::Main
注意IL_0001编译器如何创建常量“测试此函数”而不是编译器如何处理String.Concat()函数 - 它为每个.Concat()参数创建一个常量,然后调用。 Concat()函数。
答案 4 :(得分:4)
从马口:
连接是将一个字符串附加到另一个字符串末尾的过程。使用+运算符连接字符串文字或字符串常量时,编译器会创建一个字符串。没有运行时连接发生。但是,字符串变量只能在运行时连接。在这种情况下,您应该了解各种方法的性能影响。
答案 5 :(得分:2)
我相信答案是肯定的,但你必须看看编译器吐出的内容......只需编译,并在其上使用反射器: - )
答案 6 :(得分:2)
我有一个类似的问题,但关于VB.NET而不是C#。验证这个的最简单方法是在Reflector下查看编译的程序集。
答案是C#和VB.NET编译器都优化了字符串文字的连接。