我认为问题应该是自我解释的,我现在正在考虑的语言是Java,但它可能适用于所有语言。
话虽如此,基本上我所说的是这个:
// Initialize first
int i = 0;
for (i = 0; i < x; i++) {
// do some stuff
}
for (i = 0; i < x; i++) {
// do some more stuff
}
for (i = 0; i < x; i++) {
// do other stuff
}
比这更好:
// Initializing i in the for loop
for(int i = 0; i < x; i++) {
// do some stuff
}
for(int i = 0; i < x; i++) {
// do some more stuff
}
for(int i = 0; i < x; i++) {
// do other stuff
}
这是一个性能问题,我正在谈论初始化一次/每个/范围的解决方案。
答案 0 :(得分:2)
我使用x=10
执行了性能测试,以评估循环内声明方法和循环外声明方法之间的性能差异。
详细信息:我首先使用in-loop运行代码300x,然后首先使用out-loop运行300x代码。每次运行,我都以纳秒记录总运行时间,以执行10,000次方法。所以,我总共记录了1200次观察(每种方法600次)。为了测量稳态性能(副启动性能),我从每个持续时间最长的数据集中删除了20个观测值。 (20次启动观测的平均运行时间比所有其他观测值的平均运行时间大一个数量级。)
结果:单因素ANOVA表明循环内声明比循环外声明(p-value=8.12584E-07
)更快。对于环内,平均运行时间为158635.4931
纳秒,对于环外,平均运行时间为166943.7397
纳秒。从实际的角度来看,我们谈论的是每10,000次迭代的差异为~0.01ms。
结论: 只需使用循环声明。 @FallAndLearn还指出循环声明更容易维护,因为局部变量{{1}声明的范围尽可能小。
答案 1 :(得分:0)
local variables
的范围应始终为最小。
因此,如果在循环外没有使用int i
,那么第二种方式总是更好。更具可读性。
Performance
明智的他们都是same
。从maintenance
的角度来看,第二种选择更好。
此外,这个问题的答案将取决于您的要求。如果您的代码具有依赖于i的其他数据或只有三个for循环语句。
答案 2 :(得分:0)
你的第一段代码比第二段更好,因为int是一个值类型,一旦你初始化它就将它的值存储在堆栈中,稍后你只需要一次又一次地为该类型赋值。 另一方面(第二段代码),您正在初始化我三次,即创建三次堆栈条目。 所以第一段代码比第二段更好,性能明智。
答案 3 :(得分:0)
让我们查看以下代码段的反汇编代码:
DECLARE @x XML = '
<Customize xmlns="http://utsavfashion.com/web/schemas">
<customize_details>
<entityid>876</entityid>
</customize_details>
</Customize>'
DECLARE @doc INT, @xmlns VARCHAR(100)
SET @xmlns = '<root xmlns:h="http://utsavfashion.com/web/schemas" />'
EXEC sp_xml_preparedocument @doc OUTPUT, @x, @xmlns
SELECT *
FROM OPENXML(@doc, '//h:Customize/h:customize_details')
WITH (
entityid INT '.'
)
EXEC sp_xml_removedocument @doc
public class Test {
public static void main(String[] args) {
int i = 0;
for(i = 0; i < 3; i++){
//do some stuff
}
}
}
现在让我们为循环中的控制变量初始化生成另一个:
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_1
4: iload_1
5: iconst_3
6: if_icmpge 15
9: iinc 1, 1
12: goto 4
15: return
}
他们不相同,我不是字节码专家,但我可以说第二个开销较少。第一个将public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_3
4: if_icmpge 13
7: iinc 1, 1
10: goto 2
13: return
}
常量推迟两次(两个int
指令),并且与第二个代码中的一条指令相比,有两条iconst_<i>
指令。