不过,我无法决定如何实现以下代码。哪个版本的代码运行得更快?编译器会自动优化代码吗? AND 运算是否比赋值运算慢?
第一个代码:
if ((a&b) == (b&c))
{
if (a&b)
//something;
else
//something else;
}
第二个代码:
int p;
if ((p = (a&b)) == (b&c))
{
if (p)
//something;
else
//something else;
}
最佳答案
一般来说应该没什么区别,这取决于你对变量 p 做了什么。在我下面的例子中,p 从未被使用过,因此应该被优化掉,但是 gcc 对此做了一些非常有趣的事情。
unsigned int fun1 ( unsigned int a, unsigned int b, unsigned int c )
{
if ((a&b) == (b&c))
{
if (a&b)
return(1);
else
return(2);
}
}
unsigned int fun2 ( unsigned int a, unsigned int b, unsigned int c )
{
int p;
if ((p = (a&b)) == (b&c))
{
if (a&b)
return(1);
else
return(2);
}
}
因此,在您为 p 赋值的地方,它正在准备 r0 以保存该值,即使它从未被使用过。很奇怪编译器没有捕捉到。因为我没有指定返回值,所以您可以使用上面的 fun2 代码返回 p。如果您在末尾添加一个返回值,那么编译器会简单地将其添加到上述两个函数中。编译器应该也提示我没有返回值并且没有。
对于 fun1() 它似乎是在使用快捷方式来决定是否进入顶层,然后从那里开始。 Fun2 正在生成 p 变量,然后在编写 C 代码时使用它(比较 ands)。对于 fun2() 的这个实现,您将刻录一条额外的指令以使其速度变慢。如果不是 xor 快捷方式,使用这个处理器,如果它执行了两个 ands,执行时间将是相同的,编译器可以简单地决定将其中一个寄存器保留为 p 以备后用,或者只是丢弃寄存器.因此,如果您使用不同的按位运算符,您会期望两种方式的代码速度相同。
使用 llvm 而不是 gcc,还要注意我在底部添加了返回值:
unsigned int fun1 ( unsigned int a, unsigned int b, unsigned int c )
{
if ((a&b) == (b&c))
{
if (a&b)
return(1);
else
return(2);
}
return(3);
}
unsigned int fun2 ( unsigned int a, unsigned int b, unsigned int c )
{
int p;
if ((p = (a&b)) == (b&c))
{
if (a&b)
return(1);
else
return(2);
}
return(3);
}
unsigned int fun3 ( unsigned int a, unsigned int b, unsigned int c )
{
int p;
p = a&b;
if (p == (b&c))
{
if (p)
return(1);
else
return(2);
}
return(3);
}