@ operator is slow
The @ “operator” in PHP is used to silence any warnings or errors that would otherwise be shown (in the browser or the log). It’s really useful, because sometimes you know you can safely ignore a warning or error, when checking if a GET variable is set for instance. Until today I though that, if used properly and with caution, the @ operator can be freely used. Then I read this article. I really had no idea that PHP is doing so much work behind the scenes to make @ work.
When PHP comes to a statement, that contains the @ operator, it changes error reporting to none and then back, which translates to a trip to the php.ini file.
So after I stopped scratching my head and thinking “why the bloody hell would one do that like so?”, I opened my PHP editor and wrote this simple test to see just how much of a difference this makes. It’s the most common scenario where you check if a GET variable has any content.
First the version with @:
for ( $i = 0; $i < 1000000; $i++ ) {
if ( @$_GET['var'] != '' )
echo 'foo';
}
And the version without @:
for ( $i = 0; $i < 1000000; $i++ ) {
if ( IsSet ( $_GET['var'] ) && $_GET['var'] != '' )
echo 'foo';
}
I timed the execution of both snippets and here are the results:
| @ version | IsSet version | |
|---|---|---|
| 1 | 1.52496409416 | 0.196986913681 |
| 2 | 1.48627185822 | 0.204479932785 |
| 3 | 1.52267694473 | 0.206820964813 |
| 4 | 1.51263594627 | 0.207319021225 |
| 5 | 1.49150109291 | 0.199639081955 |
| 6 | 1.48829102516 | 0.174983978271 |
| 7 | 1.54369091988 | 0.206038951874 |
| 8 | 1.52254199982 | 0.204971075058 |
| 9 | 1.50641703606 | 0.190815925598 |
| 10 | 1.51343107224 | 0.203064918518 |
| sum: | 15.11242198945 | 1.995120763778 |
| avg: | 1.511242198945 | 0.1995120763778 |
The IsSet version is about 7.5 times faster, really amazing. I don't use @ as often as I used to, but I will now try to reduce it to zero. You should do the same.
Comments
Comment from david
Time June 21, 2009 at 2:16 pm
you must never use @ in you code, if you however use it, you are a really bad coder.
Comment from Jan Hančič
Time June 21, 2009 at 2:29 pm
Like I said in the post, there are valid places to use it, providing you know what you are doing. There is always an alternative to @ and you should use that, but sometimes it’s just easier to put @ infront.
But since I’ve done this test I’ll newer use it again, because it’s just too damn slow.
Comment from Tit Petric
Time June 22, 2009 at 8:05 am
It’s not really bad practice if you use @ with file_get_contents($url) (in CLI mode anyway).
But keep away from this:
@include(…)
This will just, like gasper said, completely hide all errors, including parse errors, in all included files. If you ever have such a dynamic system, that the included file might not exist when you call include(), just check it with file_exists …
But definetly avoid @ in most cases (especially in loops / where you’re too lazy to use isset).
Comment from artur ejsmont
Time September 7, 2009 at 9:55 am
I would say @ is bad no matter what.
Well maybe except cases where you check after the silenced call and throw exception if value is not there or something. But if call causes script to die you will never have chance to get throw it anyway.
@ is like swallowing exceptions …… baaaad idea.
Art
Comment from gasper_k
Time June 21, 2009 at 12:40 pm
Besides the speed issues, the problem with @ is also that it completely hides errors. Debugging an application that crashes, but doesn’t report an error, can be a nightmare. This is another one of those “let’s make it easy for the programmer” PHP things, which then come back to haunt you. We’d all be better off without @.