函数中过早返回的效率

2022-08-31 10:37:02

作为一个没有经验的程序员,我经常遇到这种情况,我想知道特别是对于我试图优化的一个雄心勃勃的,速度密集型的项目。对于主要的类C语言(C,objC,C++,Java,C#等)及其常用的编译器,这两个函数的运行效率会一样高吗?编译后的代码有什么区别吗?

void foo1(bool flag)
{
    if (flag)
    {
        //Do stuff
        return;
    }

    //Do different stuff
}

void foo2(bool flag)
{
    if (flag)
    {
        //Do stuff
    }
    else
    {
        //Do different stuff
    }
}

基本上,在早期或早期时是否有直接的效率奖金/惩罚?堆栈帧是如何参与的?是否有优化的特殊情况?是否有任何因素(如内联或“做东西”的大小)可能会对此产生重大影响?breakreturn

我一直支持提高易读性而不是小优化(我看到foo1很多参数验证),但这经常出现,我想一劳永逸地抛开所有的担忧。

而且我意识到过早优化的陷阱...呃,这些都是一些痛苦的回忆。

编辑:我接受了一个答案,但是EJP的答案非常简洁地解释了为什么使用a几乎可以忽略不计(在汇编中,创建一个“分支”到函数的末尾,这是非常快的。分支会更改PC寄存器,还可能影响缓存和管道,这是非常微不足道的。特别是对于这种情况,它实际上没有任何区别,因为和创建相同的分支到函数的末尾。returnreturnif/elsereturn


答案 1

根本没有区别:

=====> cat test_return.cpp
extern void something();
extern void something2();

void test(bool b)
{
    if(b)
    {
        something();
    }
    else
        something2();
}
=====> cat test_return2.cpp
extern void something();
extern void something2();

void test(bool b)
{
    if(b)
    {
        something();
        return;
    }
    something2();
}
=====> rm -f test_return.s test_return2.s
=====> g++ -S test_return.cpp 
=====> g++ -S test_return2.cpp 
=====> diff test_return.s test_return2.s
=====> rm -f test_return.s test_return2.s
=====> clang++ -S test_return.cpp 
=====> clang++ -S test_return2.cpp 
=====> diff test_return.s test_return2.s
=====> 

这意味着即使在两个编译器中没有优化,生成的代码也不会有任何差异


答案 2

简短的回答是,没有区别。帮自己一个忙,不要再为此担心了。优化编译器几乎总是比您聪明。

专注于可读性和可维护性。

如果你想看看会发生什么,请在优化的基础上构建这些,并查看汇编程序输出。


推荐