But the difference actual difference is so much larger. Where
does it come from? It might mean that there is some costly
operation that both `new` and `toString()` perform. Or it might
actually be a bug, and when fixed, would have worse
performance. It seems almost too good to be true...
An interesting observation:
const HTTPStatusException[10000] exc;
static this() {
for(auto i = 0; i < exc.length; i++)
exc[i] = new HTTPStatusException(HTTPStatus.NotFound);
}
void index(HTTPServerRequest req, HTTPServerResponse res)
{
throw exc[uniform(0, exc.length-1)];
}
# ab2 -n 5000 -c 1000 -k -r http://localhost:8080/
When I run this several times, I get (req/s):
933.01
1269.78
1606.49
2087.57
2512.23
2976.09
4240.72
4900.27
6136.00
6412.73
7657.19
8442.30
See a pattern? This probably means that the runtime is caching
things in the exception objects when they are thrown for the
first time. This might cause problems when they are later
rethrown from somewhere else, but I'm not sure; maybe it's
intelligent enough to recognize that case.
But notice that this still works:
auto makeExceptions(size_t n) {
auto result = new HTTPStatusException[n];
foreach(immutable i; 0 .. n)
result[i] = new HTTPStatusException(HTTPStatus.NotFound);
return result;
}
immutable(HTTPStatusException)[] exc =
assumeUnique(makeExceptions(10000));
void index(HTTPServerRequest req, HTTPServerResponse res)
{
throw exc[uniform(0, exc.length-1)];
}
If the runtime really does what I suspect, it modifies immutable
objects... So, is it legal to throw immutable (or const)
exceptions?