Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将字符串和字符组合在一起的性能_C#_.net_Types - Fatal编程技术网

C# 将字符串和字符组合在一起的性能

C# 将字符串和字符组合在一起的性能,c#,.net,types,C#,.net,Types,我想知道当我选择向常量字符串中添加一个字符或一个字符时,是否会对性能产生影响 因此,我编写了一个小型控制台应用程序:(.NET4) 静态类程序 { const string STR=“string”; 静态void Main() { var arr=新字符串[9999999]; 秒表计时器=新秒表(); Console.ReadLine(); timer.Start(); //对于(uint i=0;i

我想知道当我选择向常量字符串中添加一个字符或一个字符时,是否会对性能产生影响

因此,我编写了一个小型控制台应用程序:(.NET4)

静态类程序
{
const string STR=“string”;
静态void Main()
{
var arr=新字符串[9999999];
秒表计时器=新秒表();
Console.ReadLine();
timer.Start();
//对于(uint i=0;i<9999999;i++)
//{
//arr[i]=STR+'C';
//}
对于(uint i=0;i<9999999;i++)
{
arr[i]=STR+“C”;
}
timer.Stop();
控制台写入线(计时器延时毫秒);
Console.ReadLine();
}
}
您必须为循环注释一个

因此,
STR+“C”
大约需要1300毫秒

对于
STR+'C'
我还没有看到结果。这花的时间太长了,似乎对我的电脑造成了很大的困扰

所以,我的问题是。这种性能影响如何可能?我知道在实际使用中,9999999值的数组不会经常出现,但它仍然是一个巨大的差异


提前谢谢

像这样的简单程序:

var val = "hello ";     
val += 'r'; 
对象执行
char
值的装箱,我们可以从生成的
IL

IL_0001:  ldstr       "hello "
IL_0006:  stloc.0     // val
IL_0007:  ldloc.0     // val
IL_0008:  ldc.i4.s    72 
IL_000A:  box         System.Char
IL_000F:  call        System.String.Concat
IL_0014:  stloc.0     // val
IL_0015:  ldloc.0     // val
相反,对于
string
,它不涉及任何装箱,因此速度明显更快


那么为什么要执行拳击?因为在两个参数上调用(这是对
二进制+
运算符调用的结果),其中只有一个参数是
字符串
,会调用,因此,
char
的值被装箱,以便能够传递到该方法调用中。

这实际上很容易解释:您偶然发现C编译器将对字符串表达式执行常量折叠

由于您将
STR
声明为
const
,因此其效果是将对它的引用替换为文字字符串
“string”
。然后,当编译器遇到
“string”+“C”
时,它会用等价的
“string C”
替换该表达式。因此,实际完成的循环将花费所有时间将该字符串分配到数组中的不同位置

相反地,
char
串接并不是这样优化的,因此实际上您必须等待串接(包括分配新的
string
对象)以及数组分配。同样,循环将生成大量垃圾,因此您也在等待收集器

如果您想公平地比较这两个操作,我会做两件事:

  • STR
    的声明更改为
    static readonly
    ,而不是
    const
  • 减少迭代次数,这样您就可以真正获得完整的运行

  • 你忘了解释为什么字符是盒装的,但是字符串不是。非常感谢,回答得很好!即使没有常量
    STR+“C”
    的速度几乎是添加字符的两倍。现在我将使用单字符字符串。再次感谢@安迪很乐意帮忙。你的观察是有意义的,因为
    字符串
    可以直接连接,而不必先将
    字符
    转换为
    字符串
    。@Andy这与Tigran的回答相结合是有意义的:
    +
    操作符被调用
    string.Concat>的C#编译器取代。当您将它与字符串一起使用时,它可以直接调用接受字符串参数的重载。当您将它与char一起使用时,它必须将char装箱并调用接受对象参数的重载。装箱和拆箱操作相对昂贵,尤其是在紧密循环中执行时。但请注意,这是微优化的顶峰@科迪格雷,我支持!如果您实际上是在紧密循环中连接一个字符串,那么您肯定应该使用
    StringBuilder
    IL_0001:  ldstr       "hello "
    IL_0006:  stloc.0     // val
    IL_0007:  ldloc.0     // val
    IL_0008:  ldc.i4.s    72 
    IL_000A:  box         System.Char
    IL_000F:  call        System.String.Concat
    IL_0014:  stloc.0     // val
    IL_0015:  ldloc.0     // val