#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
");
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
";
#else
std::cout << returns << " returns
";
#endif
}
Mickey Mouse benchmarking results:
$ 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
So in this case, throwing an exception up 1000 stack levels, rather than returning normally, takes about 1.5ms. That includes entering the try block, which I believe on some systems is free at execution time, on others incurs a cost each time you enter try, and on others only incurs a cost each time you enter the function which contains the try. For a more likely 100 stack levels, I upped the repeats to 10k because everything was 10 times faster. So the exception cost 0.1ms.
For 10 000 stack levels, it was 18.7s vs 4.1s, so about 14ms additional cost for the exception. So for this example we're looking at a pretty consistent overhead of 1.5us per level of stack (where each level is destructing one object).
Obviously C++0x doesn't specify performance for exceptions (or anything else, other than big-O complexity for algorithms and data structures). I don't think it changes exceptions in a way which will seriously impact many implementations, either positively or negatively.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…