从语法上看,它们都会无限循环,直到遇到 break 语句,但它们编译成相同的东西吗?for 循环是否稍微快一些,因为它没有要检查的条件?除了代码可读性外,有什么区别吗?
从语法上看,它们都会无限循环,直到遇到 break 语句,但它们编译成相同的东西吗?for 循环是否稍微快一些,因为它没有要检查的条件?除了代码可读性外,有什么区别吗?
考虑到这个输入:
private static void ForLoop()
{
int n = 0;
for (; ; )
{
Console.WriteLine(n++);
}
}
private static void WhileLoop()
{
int n = 0;
while (true)
{
Console.WriteLine(n++);
}
}
...您将获得此输出:
.method private hidebysig static void ForLoop() cil managed
{
// Code size 14 (0xe)
.maxstack 3
.locals init ([0] int32 n)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: dup
IL_0004: ldc.i4.1
IL_0005: add
IL_0006: stloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(int32)
IL_000c: br.s IL_0002
} // end of method Program::ForLoop
.method private hidebysig static void WhileLoop() cil managed
{
// Code size 14 (0xe)
.maxstack 3
.locals init ([0] int32 n)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: dup
IL_0004: ldc.i4.1
IL_0005: add
IL_0006: stloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(int32)
IL_000c: br.s IL_0002
} // end of method Program::WhileLoop
非常相似,我会说(甚至可以说是完全一样)。
for(;;)
”被实现为单个跳转,而“while(true)
”则会检查真值。while(true)
”,因为它更清楚地表明我的意图。while(true)
比 for(;;)
更清晰明了。我到底在等什么呢? - Matthew Jonesloop: ... goto loop
? - Bertrand Marron我没有检查过输出的代码,但是不应该有任何差别。任何一个像样的编译器都会进行足够简单的循环优化,以确保条件是一个常量表达式,因此不需要每次迭代都进行检查。
如果其中一个比另一个快,那么C#编译器的作者需要解释清楚...
if (whatever) break;
)中,并将其作为循环的真正退出。
这可以而且通常应该避免。虽然有些情况下break
语句是有意义的,但它们通常应该用于处理异常情况,而不是编写一个说一件事但做另一件事的循环(即,说“永远运行”,但实际上是“运行直到满足条件”)。
while (file.getline())
而不是for (;;) if (!file.getline()) break;
。 - Jerry Coffinwhile(true)
,但为什么要费这个劲呢?这是一个真正的多重退出条件的情况,无法在顶部的单个位置确定。 - Steven Sudit调试汇编编译成while(true)。使用反射器,您可以查看结果。
static void Main(string[] args)
{
ExecuteWhile();
ExecuteFor();
}
private static void ExecuteFor()
{
for (; ; )
{
Console.WriteLine("for");
string val = Console.ReadLine();
if (string.IsNullOrEmpty(val))
{
Console.WriteLine("Exit for.");
break;
}
}
}
private static void ExecuteWhile()
{
while (true)
{
Console.WriteLine("while");
string val = Console.ReadLine();
if (string.IsNullOrEmpty(val))
{
Console.WriteLine("Exit while.");
break;
}
}
}
在Reflector中检查ExecuteFor
方法。
private static void ExecuteFor()
{
while (true)
{
Console.WriteLine("for");
if (string.IsNullOrEmpty(Console.ReadLine()))
{
Console.WriteLine("Exit for.");
return;
}
}
}
同一代码的优化版本在ExecuteFor
上产生不同的结果
private static void ExecuteFor()
{
do
{
Console.WriteLine("for");
}
while (!string.IsNullOrEmpty(Console.ReadLine()));
Console.WriteLine("Exit for.");
}
为了更加详细,这里是经过优化的ExecuteWhile
代码...
private static void ExecuteWhile()
{
do
{
Console.WriteLine("while");
}
while (!string.IsNullOrEmpty(Console.ReadLine()));
Console.WriteLine("Exit while.");
}
while(true)
,还是反编译器会这样反编译它? :p - Mark H它们编译成相同的东西。您可以编写一个测试应用程序来实现两种方法,然后使用ILDASM确认它们的IL代码是相同的。
正如其他人所提到的,使用任何现代编译器都不应该有任何区别。
我在我的电脑上进行了简短的测试,计时了一些使用其中之一的操作,它们始终需要几乎相同的时间。当然,由于其他进程正在运行,这些测试并不是100%准确的,但如果速度有差异(不应该有),那么它是微不足道的。
for(;;)
是A)由前C编程人员编写的,B)比较短四个字符 :) - hobbs