-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
Description
As thousands of times sad before, the \Exception is born-to-die class. It should not appear to top-level of the application, its like self-protection detonator - should be to improve speed of fixing.
But as i can see with PHP 8.4.5 tests following code
$mt = microtime(true);
$errors = [];
for ($i = 0; $i < 10000; $i++) {
try {
// $errors[] = new \stdClass();
throw new LogicException($i);
} catch (\Throwable $e) {
}
}
var_dump(microtime(true) - $mt);
still much slower than object creation, like 15 times slower.
I guess its about collecting backtrace on new \Exception call, but actually we DONT need that backtrace.
We dont need backtrace UNTIL we ASK for backtrace.
If your debug screen, tool or symfony dd() ask for render backtrace only then we need rows of backtrace, its arguments and so on. Also if exception becomes to log-file we're getting backtrace to simplify error search.
Old good PHP code that never throws any exceptions and uses return false we can, or even we must call unsafe because application can do actions, that we dont expect if we follow that procedure style (small scrips - ok, big enterprise - no).
So we follow the way where any function could throw the exception, but using those functions in production code without try/catch those exceptions is very un-friendly for users. Its ok for developers. Not for users.
So i see there two possible cases:
- you get unexpected exception, like typeError or something - that you must put to log and fix as fast as you can
- you write own function over existing to prevent propagation of the exception because maybe
string is empty=you cannot create email object from empty string. Maybe, correct way is to evade that case, but actually i prefer to create own types with own checks and evade to write code like:
$value = $this->to_string()->check_non_empty_string()->try_to_create_email()->check_email_is_fake();
i prefer create own function and call it like (because its short and readable):
$emailNonFake = $this->type_email_non_fake($value);
So exceptions in this case may appear billion times a day. Because functions to check email throw logic exceptions if regex pattern fails or this stuff. But type_ function over that parser will catch all the exceptions, resolve it, making value NULL or return boolean false.
Otherwise i have to write one function WITH exceptions, other function WITHOUT exceptions, just because first one is slower than second one in case of errors. Or maybe even three functions (three - with \TypeErrors to control level of the warning or something). In any case - its spending time for developer needs, not for task needs.
So much of exceptions is disappear at runtime and never become log file or debug tool.
At first, it feels like store generator with backtrace is a bad idea, but exception, that is become to log or never become to log - will be destroyed in microseconds. TTL of exception classes = time to stop application, or time to resolve catch clause. And we need trace only if we print it. When we catch exception immediate - we dont even need to know where this error appear. Of course - we can dump exception object and then generator must return whole path. But if we DONT ASK - we DONT NEED.
Could you improve performance after reading this?