C#是否优化了字符串文本的串联?
例如,编译器知道翻译吗C#是否优化了字符串文本的串联?,c#,.net,performance,optimization,C#,.net,Performance,Optimization,例如,编译器知道翻译吗 string s = "test " + "this " + "function"; 到 从而避免字符串串联对性能的影响?是的。这是由C#规范保证的。在C#3.0规范的第7.18节中: 每当表达式满足 以上列出的要求 表达式的计算时间为 编译时。这是真的,即使 表达式是表达式的子表达式 包含 非常量构造 (上述“要求”包括应用于两个常量表达式的+运算符。) 另请参见。我相信答案是肯定的,但您必须查看编译器输出的内容。。。只需编译,并在其上使用reflector:-)是的
string s = "test " + "this " + "function";
到
从而避免字符串串联对性能的影响?是的。这是由C#规范保证的。在C#3.0规范的第7.18节中: 每当表达式满足 以上列出的要求 表达式的计算时间为 编译时。这是真的,即使 表达式是表达式的子表达式 包含 非常量构造 (上述“要求”包括应用于两个常量表达式的+运算符。)
另请参见。我相信答案是肯定的,但您必须查看编译器输出的内容。。。只需编译,并在其上使用reflector:-)是的 C#不仅优化了字符串文字的串联,它还将等效的字符串文字压缩为常量,并使用指针引用同一常量的所有引用。来自: 连接是将一个字符串附加到另一个字符串末尾的过程。使用+运算符连接字符串文字或字符串常量时,编译器将创建单个字符串。没有发生运行时连接。但是,字符串变量只能在运行时连接。在这种情况下,您应该了解各种方法对性能的影响
只是一个相关主题的旁注-C编译器还将使用“
+
”运算符对String.Concat()方法的多参数重载的单个调用“优化”涉及非文本的多个串联
所以
编译成相当于
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中,编译器是如何创建常量“testthis function”的,而不是编译器如何处理String.Concat()函数的,后者为每个.Concat()参数创建一个常量,然后调用.Concat()函数。介意我将问题改为C吗?知道这是否仍然适用于插值字符串吗?我试图理解C#6规范的(草案),但是如果你不习惯阅读这样的文档,这种语言会很混乱:)@Stijn:不,插值字符串文字不是常量表达式。@JonSkeet我知道总体来说它们不是,但是是
$“hello{foo},I'm{bar}”
和$“hello{foo}”+$“I'm{bar}”
?@Stijn:不,在第二个例子中,您将分别调用string.Format
。它被称为“字符串内部调用”,在CLR via C#一书中有详细介绍。
class Program
{
static void Main(string[] args)
{
string s = "test " + "this " + "function";
string ss = String.Concat("test", "this", "function");
}
}
.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