seanmonstar

Aug 5 2010

PHP Error Suppression Performance

Sometimes, a function might cause a warning, like when you’re messing around with files. It might be tempting to just prepend an @ to the function, and live on. But being curious, I researched if this does much harm besides being sloppy/lazy. It turns out there are performance costs for doing so as well.

I first built a simple test that would loop a million times accessing a variable with and without the suppression operator prepended. The differences were small, yet noticeable. Using the suppression operator ended up taking 40% longer to execute. Interesting, but then an article by Vegard Andreas Larsen pointed out something I failed to test:

[The] assertion that it is the act of the @ operator that is very slow, is wrong. It is in fact the actual triggering of the error or warning by itself.

His tests show that while the suppression operator does add a little overhead, when an actual error1 occurs, you see a bigger cost. When using the suppression operator, you’re writing in a style that let’s you cause errors and not care, which decreases performance. The same thing applies to setting error_reporting to ignore notices or warnings. Just cause their ignored, doesn’t mean PHP doesn’t try to throw them first.

A common example is when checking for properties of an object. When ignoring notices, you might do something like this:

if($obj->prop) { 
    do_stuff($obj->prop); 
}

If the property is undefined, a notice will be thrown, and then ignored. Performance penalty. Turns out that isset is quite important, after all. Another instance could trying to call file without first calling is_file. I used to think, So what, it’s a dynamic language, it’ll be just fine. Now, I’ll be littering my code with isset everywhere.

Just to be sure, I altered my original test to check the differences between using a conditional test with isset versus just suppressing the notice. The difference was that suppressing the notice (a notice!) took 100% as long as just checking if it existed first. Try it yourself.

<?php

function no_suppress() {
    $a = 0;
    $b = new stdClass;
    $a = (isset($b->asdf) ? $b->asdf : null);
}

function suppress() {
    $a = 0;
    $b = new stdClass;
    $a = @$b->asdf ? $b->asdf : null;
}

function do_test($suppress = false, $loops = 1000000) {
    if($suppress) {
        echo "starting suppress...\n";
        $start = microtime(true);
        for($i = 0; $i < $loops; $i++) {
            suppress();
        }
        $end = microtime(true);
    } else {
        echo "starting no_suppress...\n";
        $start = microtime(true);
        for($i = 0; $i < $loops; $i++) {
            no_suppress(true);
        }
        $end = microtime(true);
    }
    echo "ended: " . ($end - $start) . "\n";
}

Now, this might not be the biggest thing in the world. But it’s enough for me to change my ways, since it affects me once to write it, and my users an infinite amount of times having to execute. Since I believe in optimizing for users instead of developers, that’s how it’s going to be.


  1. I use the term error to mean any message thrown. It includes errors, warnings, notices, etc. 


Aug 4 2010

Jul 30 2010

How I Name Boolean Variables

Naming variables is important stuff. Besides the classic “classes should be nouns, methods should be verbs” stuff, I find another very common naming convention I use is in naming my Booleans.

Particulary, I like to name them so they are a question. You can read the name of the variable, and feel you were asking a question about some object. And the question must be a yes/no question for it to work. No howAreYou variables. I make sure that it truly does sound like a question. I don’t like using single word adjectives or adverbs, like running or recommends. I’ll add is or has to make it sound like a question.

Some examples:

server.isRunning
book.isRecommended
dog.canBark
table.shouldReplace

It’s much easier to tell by looking at them that they are boolean values. Whereas, something like item.likes could actually be a number, of how many people liked the item. item.isLiked tells me that something liked the item. It’s going to be a yes or no answer to my boolean question.


+

Jul 28 2010

Jul 26 2010

Jul 23 2010

Jul 22 2010