同一函数中的异常处理会使编译时间减慢> 2x,为什么?

Meh*_*dad 6 c++ compiler-construction performance exception-handling visual-c++

我有一个数千行的项目,有一个巨大的main(约800行).
包含main函数的文件需要7.94秒才能编译.

代码结构如下:

int main(int argc, char *argv[])
{
    int result = 0;
    try
    {
        /* 800 lines of code here */
    }
    catch (std::invalid_argument const &ex)
    {
        std::cerr << ex.what() << std::endl;
        return EINVAL;
    }
    catch (std::runtime_error const &ex)
    {
        std::cerr << ex.what() << std::endl;
        return -1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我简单地将其更改为

void run(int argc, char *argv[])
{
    /* 800 lines of code here */
}

int main(int argc, char *argv[])
{
    int result = 0;
    try
    {
        run(argc, argv);
    }
    catch (std::invalid_argument const &ex)
    {
        std::cerr << ex.what() << std::endl;
        return EINVAL;
    }
    catch (std::runtime_error const &ex)
    {
        std::cerr << ex.what() << std::endl;
        return -1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时间减少到2.48秒!

我可以告诉罪魁祸首是异常处理代码,因为当我删除周围的try/时catch,我得到相同的编译时间减少.

此外,如果我将run函数标记为__forceinline,则编译时间增加到 10.02!但是如果我在拿出try/ 之后这样做catch,那么它会下降到仅仅3.27秒.

但是给出了什么?当代码直接位于try块体内时,编译器究竟需要做什么才会变得更加计算密集?

笔记:

  • 我在RELEASE模式下编译
  • Microsoft Visual C++ 2013年11月CTP编译器(本机x64)
  • 相关的编译器选项:( /O2 /Gm- /GS /EHsc删除/EHsc也加快了编译速度)

Ofe*_*lon 1

我怀疑差异与额外的清理代码有关。函数中声明的 C++ 对象在离开函数时就会被销毁,因此它们的销毁代码已经在函数尾声中,并且(我认为)堆栈展开(异常处理过程的一部分)可以利用该代码。如果您需要在不离开函数的情况下销毁所有这些对象,则需要生成和管理额外的销毁代码,这可能会影响构建时间和二进制大小。你能说二进制大小是否有差异吗?

尽管坦率地说,我很惊讶影响(时间/大小)是可以衡量的。“800 行”在 C++ 对象创建方面是否异常丰富?(也许是间接的)