How expensive is it to create an exception in PHP?
Back story: I have a class that handles a database query. The problem is that the query is only executed when needed, so this may sometimes be a bit far away from the place it's created. Now if the wrapped SQL query fails, it becomes difficult to trace it back to it's origin.
开发者_如何学编程Now the idea is this: I'll create a generic exception object (which gives me backtrace and everything) when creating that wrapper. When something happens during the actual execution, the pre-generated exception can be used to find the source of the problem when debugging.
This inevitably leads to the question: How expensive is it to generate an Exception
object beforehand? Is it even a smart thing to do? How would you debug deferred SQL execution?
To clarify the process, here's some pseudo code:
$list = new QueryWrapper("SELECT ...");
$list->setPage(5);
// Later...
foreach ($list as $entry) { ... }
Only when the foreach actually accesses $list
is the query executed.
Update: Here's a minimalistic implementation:
public function __construct($query, ... $params = array()) {
...
$this->createTrace = new \Exception();
}
// called by the Iterator's rewind()
private function runQuery() {
try {
// execute query;
}
catch(\Exception $e) {
throw new \Exception(
sprintf(
'Exception thrown after SQL error (created as %s)',
$this->createTrace->getTraceAsString()
),
0, $e
);
}
}
Instantiating an Exception which might be thrown later sounds like a rather unusual idea and is likely not what I would expect. I mean, the normal case would be to NOT throw an exception. So, most of the time you would create an Exception which is likely be never thrown/used.
An Exception which is thrown later in program flow will give you the stack trace anyway, so in my opinion: dont bother and dont do that.
In a production environment, I believe that the performance "loss" would be negligible as creating an Exception
object is the same as creating any class, which is virtually no hit whatsoever.
I'm not sure that this is the correct way to approach your problem however.. Is this what you're expecting to do?
$list = new QueryWrapper("SELECT ...");
$list->exception = new Exception();
?
A simple 3v4l test:
- create exception: https://3v4l.org/ACHS0/perf#output
- do not create exception: https://3v4l.org/XRojg/perf#output
The difference seems to be minimal (on the 3v4l.org hardware, about 1-10 us per exception creation - that's less than a millisecond if you run a few dozen queries per request, not really relevant even for a high-performance web application).
精彩评论