在C++中测量异常处理开销/性能的最佳方法是什么?
请提供独立的代码示例.
我的目标是Microsoft Visual C++ 2008和gcc.
我需要从以下案例中获得结果:
没有try/catch块时的开销
有try/catch块时的开销但不抛出异常
抛出异常时的开销
Xavier Nodet.. 34
C++性能技术报告草案的第5.4节完全专注于异常的开销.
C++性能技术报告草案的第5.4节完全专注于异常的开销.
作为建议:抛出异常时不要过多担心开销.异常处理实现通常不会快速抛出并缓慢捕获.没关系,因为那些案例非常特殊.
卡尔
这是我想出的测量代码.你觉得它有什么问题吗?
到目前为止适用于Linux和Windows,编译:
g++ exception_handling.cpp -o exception_handling [ -O2 ]
或者例如Visual C++ Express.
要获得基本案例("完全从语言中删除异常支持"),请使用:
g++ exception_handling.cpp -o exception_handling [ -O2 ] -fno-exceptions -DNO_EXCEPTIONS
或MSVC中的类似设置.
这里有一些初步结果.由于机器负载的不同,它们可能都很糟糕,但它们确实对相关的异常处理开销有所了解.(执行摘要:当没有异常被抛出时,没有或很少,当它们实际被抛出时是巨大的.)
#include// Timer code #if defined(__linux__) #include #include double time() { timeval tv; gettimeofday(&tv, 0); return 1.0 * tv.tv_sec + 0.000001 * tv.tv_usec; } #elif defined(_WIN32) #include double get_performance_frequency() { unsigned _int64 frequency; QueryPerformanceFrequency((LARGE_INTEGER*) &frequency); // just assume it works return double(frequency); } double performance_frequency = get_performance_frequency(); double time() { unsigned _int64 counter; QueryPerformanceCounter((LARGE_INTEGER*) &counter); return double(counter) / performance_frequency; } #else # error time() not implemented for your platform #endif // How many times to repeat the whole test const int repeats = 10; // How many times to iterate one case const int times = 1000000; // Trick optimizer to not remove code int result = 0; // Case 1. No exception thrown nor handled. void do_something() { ++result; } void case1() { do_something(); } // Case 2. No exception thrown, but handler installed #ifndef NO_EXCEPTIONS void do_something_else() { --result; } void case2() { try { do_something(); } catch (int exception) { do_something_else(); } } // Case 3. Exception thrown and caught void do_something_and_throw() { throw ++result; } void case3() { try { do_something_and_throw(); } catch (int exception) { result = exception; } } #endif // !NO_EXCEPTIONS void (*tests[])() = { case1, #ifndef NO_EXCEPTIONS case2, case3 #endif // !NO_EXCEPTIONS }; int main() { #ifdef NO_EXCEPTIONS printf("case0\n"); #else printf("case1\tcase2\tcase3\n"); #endif for (int repeat = 0; repeat < repeats; ++repeat) { for (int test = 0; test < sizeof(tests)/sizeof(tests[0]); ++test) { double start = time(); for (int i = 0; i < times; ++i) tests[test](); double end = time(); printf("%f\t", (end - start) * 1000000.0 / times); } printf("\n"); } return result; // optimizer is happy - we produce a result }