2011-03-02 38 views
5

我有哪里我声明了一个对象在循环中,如代码之外的对象的任何性能增益:是否存在被宣告循环

foreach(...) 
{ 
ClassA clA = new ClassA(); 
clA.item1=1; 
clA.item2=2; 
ClassB.Add(clA); 
} 

会有任何性能增益,如果我修改代码如下:

ClassA clA; 
foreach(...) 
{ 
clA = new ClassA(); 
clA.item1=1; 
clA.item2=2; 
ClassB.Add(clA); 
} 

在此先感谢。

+0

我没有想到这样你还是每次创建一个新的ClassA的。你有多少个循环? ClassB.Add是做什么的? – 2011-03-02 11:13:35

+0

[将在循环内部/外部声明变量会改变性能吗?](http://stackoverflow.com/questions/3388536/will-declaring-a-variable-inside-outside-a-loop-change-性能) – 2011-03-02 11:17:14

回答

4

没有性能增益。它只能帮助变量早于范围超出范围。

+1

没错。 .NET GC将做一个合适的清理工作。 :) – FarligOpptreden 2011-03-02 11:12:41

+2

如果循环后没有使用变量,则范围界定纯粹是词法,即。你可以编写代码在更多的地方使用它。但是,对于GC目的而言,它没有任何区别(至少在没有附加调试器的Release版本中),只要循环结束,GC就可以回收内存。 – 2011-03-02 11:14:47

+1

我将添加@Farlig所说的内容:MICROSOFT运行时将很容易地看到在循环之后clA不再被使用,并且它也是GC。这不能保证。一个不太智能的JIT无法看到这一点(甚至一个偶然的JIT无法检查在内部作用域中定义的clA是不是外部复制的,而且可以肯定的是,在下一次GC运行之前不会将其标记出来。我写了一个很复杂的方式,假设有一个List 在范围之外,如果你将clA添加到列表中,列表将会保留它,如果你不添加它,列表将不会保留它。愚蠢的JIT无法检查这个。) – xanatos 2011-03-02 11:17:38

3

编译器会自动优化代码以将声明移到循环之外,所以这样做没有任何好处。

例如

while(...){ 
    int i = 5; 
    ... 
} 

将得到优化是编译器到这

int i; 
while(...){ 
    i = 5; 
    ... 
} 
+3

顺便说一句,这两个并不等价:第一个在每个循环的顶部初始化'i'到5。你对这个声明是正确的,这只是你的代码示例是混乱的。第二个会更好,因为我int; while(...){i = 5; ''。 – paxdiablo 2011-03-02 11:14:28

+0

@pax - Ops!现在修复了我的代码。谢谢。 – 2011-03-02 13:02:41

1

实际的对象分配情况与clA = new ClassA();所以,除非你可以把它移到圈外的,你不会得到任何性能增益。

1

由于每个人的说,不是真的,但我还是会改变你的代码:

foreach(...) 
{ 
ClassB.Add(new ClassA() { item1=1, item2=2 }); 
} 
+0

你当然可以做到这一点,但你为什么认为这是可取的? – 2011-03-03 04:40:44

+0

只是因为它看起来更好......(没有临时变量只是为了分配属性)。虽然你可能想调整空白,但我懒得在SO中对事物进行美化。 – Massif 2011-03-03 08:55:48

相关问题