C# 在循环内部/外部声明变量会改变性能吗?

C# 在循环内部/外部声明变量会改变性能吗?,c#,C#,这是: foreach(Type item in myCollection) { StringBuilder sb = new StringBuilder(); } 比以下速度慢得多: StringBuilder sb = new StringBuilder(); foreach(Type item in myCollection) { sb = new StringBuilder(); } 换句话说,我在哪里声明我的StringBuilder真的很重要吗?不,从性能角度讲,在

这是:

foreach(Type item in myCollection)
{
   StringBuilder sb = new StringBuilder();
}
比以下速度慢得多:

StringBuilder sb = new StringBuilder();

foreach(Type item in myCollection)
{
   sb = new StringBuilder();
}

换句话说,我在哪里声明我的
StringBuilder
真的很重要吗?

不,从性能角度讲,在哪里声明它并不重要


对于一般代码清洁度,您应该在使用它的最内部范围内声明它-即您的第一个示例。

在第二个示例中,您正在创建一个额外的StringBuilder实例。除此之外,它们都是相同的,因此性能问题是可以忽略的。

这里没有足够的代码来清楚地指出特定情况下的性能差异。话虽如此,在大多数情况下,在循环内部声明一个引用变量与在外部声明一个引用变量之间的区别是微不足道的。

如果编写以下代码,您可能会获得一些性能:

StringBuilder sb = new StringBuilder();
foreach(Type item in myCollection)
{
   sb.Length = 0;
}

因此,您只需实例化StringBuilder一次,并重置循环中的大小,这应该比实例化新对象稍快。

两个代码示例之间的有效区别是,第二个示例将比第一个实例多分配一个
StringBuilder
。与应用程序的其他部分相比,这种方法对性能的影响基本上是零。

最好的检查方法是在一个循环中尝试这两种方法,每种方法大约100.000次。测量每100.000次迭代所花费的时间,并进行比较。我认为没有太大区别。 但是有一点不同。第一个示例的变量数量与迭代次数相同。第二个示例只有一个变量。编译器足够聪明,可以在这里进行一些优化,因此您不会注意到速度的提高。
但是,如果您不想再次在循环外部使用在循环内部生成的最后一个对象,那么第一个解决方案会更好。在第二种解决方案中,垃圾收集器释放最后创建的对象只需要一段时间。在第一个示例中,垃圾收集器释放对象的速度会快一点。这取决于代码的其余部分,但是如果您在这个StringBuilder对象中存储了大量数据,那么第二个示例可能会占用这个内存更长的时间,从而在退出循环后降低代码的性能
再说一次,如果对象占用100KB,而您的计算机中有16GB,那么没有人会在意。。。垃圾回收器最终会再次释放它,很可能在您离开包含此循环的方法时释放。

如果您有其他类似的类型代码段,您可以随时分析或在代码周围放置一些计时器,并运行基准类型测试以亲自查看。另一个因素是内存占用,其他人对此发表了评论。

无论如何,我认为这应该编译成相同的IL。好吧,如果他没有两次初始化sb,那会的。如果我错了,请纠正我,但是如果你在循环内声明它,那么在循环外它不会变得不可用(未声明)?@NullUserException是的,你是对的。但是,如果你不需要在循环外使用它,那么在循环内声明它就更清楚了。在我看来,这应该是对这个问题的一个评论。@Shaihi-为什么?w69rdy正在回答这个问题。类似于一个不相关的错误,第二个版本应该初始化为null以避免过度分配。+1:根据生成字符串的大小和sb中产生的内部缓冲区,这可能会产生可测量的差异。可能会,但也可能不会。当您调用
ToString
时,它会复制缓冲区。我会对它进行基准测试,假设有任何理由认为它对性能敏感。