C#是否优化了string文字的连接?
例如,编译器是否知道翻译
string s = "test " + "this " + "function";
至
string s = "test this function";
从而避免string连接的性能打击?
是。 这是由C#规范保证的。 它在7.18节(C#3.0规范)中:
只要expression式满足上面列出的要求,expression式就会在编译时进行评估。 即使expression式是包含非常量结构的较大expression式的子expression式,情况也是如此。
(“上面列出的要求”包括应用于两个常量expression式的+运算符。)
另见这个问题 。
只是关于相关主题的附注 – C#编译器还会使用“ +
”运算符对“String.Concat()”方法的多参数重载的单个调用“优化”涉及非文字的多个连接。
所以
string result = x + y + z;
编译成相当于
string result = String.Concat( x, y, z);
而不是更天真的可能性:
string result = String.Concat( String.Concat( x, y), z);
没有什么惊天动地的,但只是想把这一点添加到关于string文字串联优化的讨论中。 我不知道这个行为是否由语言标准来规定。
是。
C#不仅优化了string文本的连接,还将等价的string文本折叠为常量,并使用指针引用对同一常量的所有引用。
是的 – 您可以使用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中编译器如何创build常量“test this function”,而不是编译器如何处理String.Concat()函数,该函数为每个.Concat()参数创build一个常量,然后调用.Concat()function。
从马口:
连接是将一个string追加到另一个string的末尾的过程。 当通过使用+运算符连接string文字或string常量时,编译器会创build一个string。 没有运行时串联发生。 但是,stringvariables只能在运行时连接。 在这种情况下,您应该了解各种方法的性能影响。
我相信答案是肯定的,但你必须看看编译器吐出来的东西…只是编译,并使用reflection器:-)
我有一个类似的问题,但关于VB.NET而不是C#。 validation这个最简单的方法是在Reflector下查看已编译的程序集。
答案是C#和VB.NET编译器都会优化string的连接。