【发布时间】:2010-09-22 06:34:17
【问题描述】:
例如,编译器是否知道翻译
string s = "test " + "this " + "function";
到
string s = "test this function";
从而避免字符串连接对性能的影响?
【问题讨论】:
标签: c# .net performance optimization
例如,编译器是否知道翻译
string s = "test " + "this " + "function";
到
string s = "test this function";
从而避免字符串连接对性能的影响?
【问题讨论】:
标签: c# .net performance optimization
是的。这是由 C# 规范保证的。它在(C# 3.0 规范的)第 7.18 节中:
每当一个表达式满足 上面列出的要求, 表达式在 编译时。这是真的,即使 表达式是 a 的子表达式 更大的表达式,包含 非常量构造。
(“上面列出的要求”包括应用于两个常量表达式的 + 运算符。)
【讨论】:
$"hello {foo}, i'm {bar}" 和$"hello {foo}" + $"i'm {bar}" 一样吗?
string.Format。
我相信答案是肯定的,但是您必须查看编译器吐出的内容...只需编译并在其上使用反射器 :-)
【讨论】:
是的。
C# 不仅优化了字符串字面量的串联,它还把等价的字符串字面量折叠成常量,并使用指针来引用同一个常量的所有引用。
【讨论】:
来自马口:
连接是将一个字符串附加到另一个字符串末尾的过程。当您使用 + 运算符连接字符串文字或字符串常量时,编译器会创建一个字符串。不会发生运行时连接。但是,字符串变量只能在运行时连接。在这种情况下,您应该了解各种方法的性能影响。
【讨论】:
只是一个相关主题的旁注 - C# 编译器还将使用“+”运算符“优化”涉及非文字的多个连接,以对 String.Concat( ) 方法。
所以
string result = x + y + z;
编译成等价于
string result = String.Concat( x, y, z);
而不是更天真的可能性:
string result = String.Concat( String.Concat( x, y), z);
没什么惊天动地的,只是想在关于字符串字面连接优化的讨论中添加这一点。我不知道这种行为是否是语言标准规定的。
【讨论】:
我有一个类似的问题,但关于 VB.NET 而不是 C#。验证这一点的最简单方法是在 Reflector 下查看已编译的程序集。
答案是 C# 和 VB.NET 编译器都优化了字符串文字的串联。
【讨论】:
是的 - 您可以使用 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() 函数。
【讨论】: