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

这是:

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

慢得多:

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

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

如果你写这个,你可能会获得一些表现:

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

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

不,在声明它的情况下,性能方面无关紧要。

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

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

这里没有足够的代码来清楚地表明您的具体情况的性能差异。 话虽如此,在大多数情况下,在这样的循环内声明参考变量与外部之间的区别是微不足道的。

两个代码示例之间的有效差异是第二个将分配比第一个更多的StringBuilder实例。 与其他应用程序相比,这对性能的影响基本上没有。

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

如果您有其他类似的类型代码段,您可以随时在代码中分析或放置一些计时器并运行基准类型测试以便自己查看。 另一个因素是内存占用,其他人已经评论过。