c++ - 抛出 C++0x 异常的代价

标签 c++ performance exception

在 C++0x 中抛出异常对性能有何影响?这个编译器依赖多少?这和问 what is the cost of entering a try block, even if no exception is thrown 不一样.

我们是否应该期望像在 Java 中那样将异常更多地用于一般逻辑处理?

最佳答案

#include <iostream>
#include <stdexcept>

struct SpaceWaster {
    SpaceWaster(int l, SpaceWaster *p) : level(l), prev(p) {}
    // we want the destructor to do something
    ~SpaceWaster() { prev = 0; }
    bool checkLevel() { return level == 0; }
    int level;
    SpaceWaster *prev;
};

void thrower(SpaceWaster *current) {
    if (current->checkLevel()) throw std::logic_error("some error message goes here\n");
    SpaceWaster next(current->level - 1, current);
    // typical exception-using code doesn't need error return values
    thrower(&next);
    return;
}

int returner(SpaceWaster *current) {
    if (current->checkLevel()) return -1;
    SpaceWaster next(current->level - 1, current);
    // typical exception-free code requires that return values be handled
    if (returner(&next) == -1) return -1;
    return 0;
}

int main() {
    const int repeats = 1001;
    int returns = 0;
    SpaceWaster first(1000, 0);

    for (int i = 0; i < repeats; ++i) {
        #ifdef THROW
            try {
                thrower(&first);
            } catch (std::exception &e) {
                ++returns;
            }
        #else
            returner(&first);
            ++returns;
        #endif
    }
    #ifdef THROW
        std::cout << returns << " exceptions\n";
    #else
        std::cout << returns << " returns\n";
    #endif
}

米老鼠基准测试结果:

$ make throw -B && time ./throw
g++     throw.cpp   -o throw
1001 returns

real    0m0.547s
user    0m0.421s
sys     0m0.046s

$ make throw CPPFLAGS=-DTHROW -B && time ./throw
g++  -DTHROW   throw.cpp   -o throw
1001 exceptions

real    0m2.047s
user    0m1.905s
sys     0m0.030s

所以在这种情况下,将异常抛出 1000 个堆栈级别,而不是正常返回,大约需要 1.5 毫秒。这包括输入 try block ,我相信在某些系统上它在执行时是免费的,在其他系统上每次输入 try 都会产生成本,而在其他系统上只会在每次输入包含 try 的函数时产生成本。对于更有可能的 100 个堆栈级别,我将重复次数提高到 10k,因为一切都快了 10 倍。所以异常花费了 0.1ms。

对于 10 000 个堆栈级别,它是 18.7 秒与 4.1 秒,因此异常的额外成本约为 14 毫秒。因此,对于这个示例,我们正在查看每层堆栈 1.5us 的相当一致的开销(其中每一层都破坏一个对象)。

显然 C++0x 没有指定异常的性能(或其他任何东西,除了算法和数据结构的大 O 复杂性)。我不认为它改变异常的方式会严重影响许多实现,无论是正面还是负面。

关于c++ - 抛出 C++0x 异常的代价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1018800/

相关文章:

c++ - std::string.assign(NULL) 的行为?

c++ - 使用 Boost Spirit/Fusion 轻松解析带有枚举字段和 STL 容器的结构

x86-64 程序集的性能优化 - 对齐和分支预测

c# - 调试时忽略某个位置的异常?

c# - Xml 反序列化在空元素上失败

ios - Swift 中的“NSInternalInconsistencyException”

java - 使用 JNI 从 C++ 程序执行 java jar,使用 g++ 或 eclipse

c++ - 无法使用 strptime() 获取秒数

java - bindView switch-case 性能问题

performance - 强制预计算一个常数