我很好奇是否以不同的方式编写if
语句会影响程序的速度和效率。因此,例如编写这样的代码:
bool isActive = true;
bool isResponding = false;
if (isActive && isResponding)
{
//do this
}
是否比:
if (isActive)
{
if (isResponding)
{
// do this
}
}
或者反之亦然,或者根本没有区别吗?我问这个if
语句的原因是因为AND &&
及其编译后创建的asm
函数的数量。或如何:
if (isActive || isResponding)
{
//do this
}
这比以下方法更理想:
if (isActive)
{
//do this #1
}
else if (isResponding)
{
//do this #1
}
//do this #2
就像使用AND &&
一样,我很好奇,因为OR ||
答案 0 :(得分:3)
不,它不会影响性能,因为&&
和||
被称为“短路运算符”,也就是说,如果其中没有任何意义,则不会触发它们链接的语句。这样做。
例如
if( true && myBoolFunc() )
-myBoolFunc
将触发,因为在检查true
之后,我们仍然不知道整个语句是否为真。
if( false && myBoolFunc() )
-myBoolFunc
将不会触发,因为在检查false
后,我们已经知道整个语句是错误的。
if( true || myBoolFunc() )
-myBoolFunc
将不会触发,因为在检查true
之后,我们已经知道整个语句都是正确的。
if( false || myBoolFunc() )
-myBoolFunc
将被触发,因为在检查false
之后仍然不知道整个语句是否为假。
如果您想了解有关其工作原理的更多详细信息,只需阅读此Wikipedia article
答案 1 :(得分:1)
我只是出于好奇而测量,结果并没有说明两者之间存在差异。
测试代码:
private static void testIfs()
{
int count = 100000;
{
Stopwatch w = Stopwatch.StartNew();
int test = 0;
bool isActive = true;
bool isResponding = false;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive && isResponding)
test++;
test = 0;
isActive = false;
isResponding = true;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive && isResponding)
test++;
w.Stop();
Console.WriteLine("using &&: " + w.ElapsedTicks);
}
{
Stopwatch w = Stopwatch.StartNew();
int test = 0;
bool isActive = true;
bool isResponding = false;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive)
if (isResponding)
test++;
test = 0;
isActive = false;
isResponding = true;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive)
if (isResponding)
test++;
w.Stop();
Console.WriteLine("using 2 ifs: " + w.ElapsedTicks);
}
{
Stopwatch w = Stopwatch.StartNew();
int test = 0;
bool isActive = true;
bool isResponding = false;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive || isResponding)
test++;
test = 0;
isActive = false;
isResponding = true;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive || isResponding)
test++;
w.Stop();
Console.WriteLine("using ||: " + w.ElapsedTicks);
}
{
Stopwatch w = Stopwatch.StartNew();
int test = 0;
bool isActive = true;
bool isResponding = false;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive)
test++;
else if (isResponding)
test++;
test = 0;
isActive = false;
isResponding = true;
for (int j = 0; j < count; j++)
for (int i = 0; i < count; i++)
if (isActive)
test++;
else if (isResponding)
test++;
w.Stop();
Console.WriteLine("using else if: " + w.ElapsedTicks);
}
}
尝试一些(启用优化代码的发布版本):
using &&: 21449771
using 2 ifs: 20845600
using ||: 21025834
using else if: 21018318
using &&: 21041437
using 2 ifs: 21899080
using ||: 20442059
using else if: 21345493
using &&: 20629055
using 2 ifs: 20135598
using ||: 20407510
using else if: 20264467
using &&: 20152862
using 2 ifs: 19676131
using ||: 19910502
using else if: 19918131
答案 2 :(得分:0)
对于您所建议的方案没有任何影响。编译器会自动处理它并执行大量优化。
但是,即使编译器也有局限性。它不知道哪些值通常会分配给变量。作为开发人员,您会知道的。
在您的示例中:
main
很明显,如果bool isActive = <RETVAL_OF_SOME_FUNCTION>;
bool isResponding = <RETVAL_OF_SOME_FUNCTION>;
if (isActive && isResponding)
{
//do this
}
为假,我们就不必为isResponding
而烦恼。因此,isActive
应该在AND条件的语句序列中首先出现。这样可以确保在运行时,isActive
为假时不会浪费检查isResponding
的处理能力。(如果{{1 }}是错误的)
尽管这是一个很小的优化,但编译器不会完成。编译器将不知道变量代表什么。它只会寻找预编程的优化并实现它。
在这种“与”或“或”的级联中,控制条件应始终优先。
可能存在两种性能下降的情况:
答案 3 :(得分:-4)
实际上,在此示例中,语句之间的区别在于基本指令的数量:
if (isActive && isResponding){
//do this}
在这里,CPU将计算isActive 和 isResponding,而不是检查结果是否为0或1 否则,在其他代码中,他将做2检查如果在很长时间内多次重复执行 if 语句,则会发现性能差异 我希望我能帮忙