创建串联字符串的性能

时间:2013-03-10 21:27:16

标签: c# string performance

C#

中,创建字符串的方式更有效

数字1:

bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");

数字2:

bool value = true;
String channel = "1";
string  s = ":Channel" + channel + ":Display " + value ? "ON" : "OFF";

4 个答案:

答案 0 :(得分:7)

我现在要添加一个例子来说明编译器如何对待这两个,因为在其他一些答案中似乎存在 很多 的混淆(编辑:请注意,这些混淆中的大部分现已被删除/编辑掉了):

bool value = true;
int channel = 1;
String s = String.Format(":Channel{0}:Display {1}", channel,
    value ? "ON" : "OFF");

最后一行编译为:

String s = String.Format(":Channel{0}:Display {1}",
    new object[2] {(object)channel, value ? "ON" : "OFF")};

有趣地注意为int channel创建数组和“框”,当然还需要额外的解析来查找{0} / {1}

现在编号2:

bool value = true;
String channel = "1";
string  s = ":Channel" + channel + ":Display " + (value ? "ON" : "OFF");

最后一行编译为:

string s = string.Concat(":Channel", channel, ":Display ", value ? "ON" : "OFF");

这里没有数组,没有框(channel现在是一个字符串),没有解析。重载是public static string string.Concat(string,string,string,string); string.Concat非常有效地实现,预先分配正确大小的字符串,然后覆盖,等等。

在大多数代码中,要么就好了。第二个版本在技术上更高效(没有盒子,没有数组,没有解析),但如果你想稍后进行国际化,这是一个很大的痛苦。在大多数应用程序中,您不会注意到两者之间的任何差异。解析速度很快,并且盒子/数组被廉价地收集为gen-zero对象。但廉价不是免费的。

答案 1 :(得分:6)

这可以帮助您自己测试。这是使用.net v4.0.30319运行时执行的。

sw = new System.Diagnostics.Stopwatch();

// Number 1
bool value = true;
int channel = 1;
sw.Start();
for (int i = 0; i <= 100000; i++)
{
    String s = String.Format(":Channel{0}:Display {1}", channel, value ? "ON" : "OFF");
}
sw.Stop();

sw.Reset();

// Number 2
sw.Start();
for (int i = 0; i <= 100000; i++)
{
    string s = "Channel" + channel + ":Display " + (value ? "ON" : "OFF");
}
sw.Stop();

我的结果是:

  

数字1:136毫秒

     

2号:91毫秒

所以第二种选择有更好的表现。事实上,第一个选项使用额外的方法调用(string.Format())并替换参数(如Marc所说)是产生差异的原因。

如果不使用100.000次迭代,我使用1.000.000,这就是我得到的

  

数字1:1308ms

     

2号:923毫秒

基本上,同样的结论。

答案 2 :(得分:0)

关于Marc Gravell的回答:您可以通过传递channel.ToString()来避免装箱操作。我已经经过验证,这对#1和#2都有轻微的性能提升。

  • 在#1的情况下,您可以避免装箱操作。
  • 如果是#2,则避免调用隐式转换运算符。

但是在试图反驳你的理论之后(用更长的连接和随机字符串)我必须承认#2比#1更快。

答案 3 :(得分:-4)

1号是最有效的。

String.Format()函数在内部使用System.Text.StringBuilder类型来连接字符串。

StringBuilder用于表示可变(也称为可编辑)字符串,它是连接字符串的最有效方法。 http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx