Know what to use where

Making something in PHP isn’t hard. Things get harder when it needs to be secure and when speed becomes relevant. But what to do when things really have to be at there absolute fastest? What if every µsecond counts? What if a single extra CPU cycle needed to run your script can cost a man his life? Read on.
Ok, so an extra CPU cycle needed to run a PHP script won’t save lives.. I thought it sounded nice.
I oftenly see people use functions in places where, sure, they work, but others would do the exact same, much faster. And to be honest, I can’t blame those people. Its not like there is a guide on it (if there is / you have one, leave a comment with the URL, please. Thanks.) and figuring out what function can do something the fastest requires you to know all functions that can do what you want, plus doing some decent testing on all of them. The latter is a big problem, ’cause as we all know, us programmers are lazy. πŸ˜‰ Anyway, for those that really are, I’m going to post some of the benchmarks I ran myself on stuff.

How I benchmark

First a short elaboration on how I run my benchmarks.
I benchmark things at a verry basic level. Setup some stuff, start a timer, do something xx times (normally 100,000 or 1,000,000, though it may be up or down a zero for verry light or heavy things.), run what I’m comparing it against the same ammoung of times, print out how long both took. Like I said, verry basic. πŸ™‚ Note to self: Finish that class for automating this, soon..
For those who care: I run stuff on a Intel Pentium 4, 3066 MHz (23 x 133) (Northwood HyperThreading), 2 X Corsair VS1GB400C3, plugged into a MSI MS-6575E motherboard. My OS of use is Windows XP Professional running Apache/2.0.59 & PHP/5.2.0. (That about sums it up, right?)

isset() vs array_key_exists()

Note that there is a difference between the two. isset($array[$index]) returns false even if it is actually set to NULL, whereas array_key_exists() returns true. Thank you Jeremy for pointing this out.For a project I’m working on with Pete, I’m oftenly checking if an index is set in a array. I normally use isset to do this, but sometimes, for no reason, use array_key_exists() instead. When I looked over some code I has written, I noticed this, and decided to see which is better. I used an array containing incremently more letters of the alphabet, untill an element held all. (So 0 => ‘a’, 1 => ‘ab’,…24 => ‘abc…xyz’) I then had both isset() and array_key_exists() check elements 0 trough 26 (of which all but 26 would be set) 1,000,000 times. (So, 27,000,000 calls to both functions.) There are the results:

In total, this benchmark took 16.87498 seconds.
Times where spend like this:
isset() took 1.5900671482 seconds.
array_key_exists() took 15.2848100662 seconds.

This suprised me, as I would have assumed array_key_exists would be faster. I then wondered, would there be a difference if the keys would be alphanumerical, instead of just numerical?
So, first, I made another benchmark. It was exactly the same, except for the array used; it now was array(‘a’ => ‘a’,…’abc..xyz’=>’abc…xyz’); I did still have both functions check if a numerical value was set. While not 100% unexpectable, this didn’t seem to make a big difference. I then had the functions call the alphanumerical indexes (‘a’ => ‘abc..xyz’) and as 27th check, I used ‘zyx..cba’. My results:

In total, this benchmark took 23.82291 seconds.
Times where spend like this:
isset() took 4.5246219635 seconds.
array_key_exists() took 19.2981789112 seconds.

While still not exactly what I expected (a function written to check if a key is set in an array should be faster then a function written to check if a variable is set and that happens to be able to do the same for array indexes, right?) I do find the relative increases interesting. Even though isset() is still much faster, it seems array_key_exists() is has much less problems with strings. (Note: I tested with different lengh loops, and found that the fact that the used time went up about 4 seconds for each is a coincidense.) I won’t write a conclusion, because I suck at writing those don’t want to make my own thoughts seem like facts, but I know I’ll be sticking with isset() from now on. Isset(), faster in executing and writing. πŸ˜€ Oh, if your interested in seeing what exactly I did, and how it runs on your system (users of other platforms, both hard- as softwarematic, I’d like to see your results.), just for you, I uploaded a package containing the file here.

Thats it

for now, at least. Yea, I suck at writing out more then one thing at a time. I’m going to post follow-up articles lateron. I hope somebody gets something usefull out of this. πŸ˜›

About Jory

Born in 1988, Software Engineer (BA), dutch. Will ad more later.
This entry was posted in PHP. Bookmark the permalink.

4 Responses to Know what to use where

  1. Couple of things to take note of:

    First, isset() is a language construct and not a function. As such, it’s inherently going to be faster than any related function ever could be.

    Second, depending on the functionality you’re looking for, array_key_exists() might be a better choice. If you check out the manual page for array_key_exists() there’s a section defined specifically to point out the differences between it and isset(). You’ll want to use this to judge which method is most appropriate to use, based on your situation. 9 times out of 10, isset() has been perfect for my personal needs, though.

    As far as the benchmarks go, the margin was considerably smaller for me, because the overall script execution time was only about 2 seconds, but array_key_exists() filled over 1.65 of those 2 seconds.

  2. Jory says:

    True, the effects of isset() and array_key_exists() is somewhat different, I should have mentioned that. But as I, and most others, will normally want to know if a $var set to something usefull, which NULL really isn’t, you’ll just want to use the faster one anyway. Thanks for the heads-up though, I’ll add a note about it. πŸ™‚

    Oh, and 19 / 24 = .79, 1.65 / 2 = 0.825, so the relative difference is about the same, don’t you think? πŸ˜‰
    (btw, with times like that, was are you testing on? πŸ˜› )

  3. For the test machine, I used my development laptop. A Toshiba Satellite with an Intel Core Duo processor clocking in at 3.2 Ghz with 2 GB of RAM.

    I’m actually surprised that I got that kind of result, considering how loaded down my laptop is constantly with all of my development tools.

    Apache / MySQL & IIS / MSSQL are always running, and I usually have both Zend Studio and Visual Studio open at the same time. Not to mention multiple browsers. Microsoft Word, OneNote, and Outlook … You get the idea. πŸ˜›

  4. Oh, and 19 / 24 = .79, 1.65 / 2 = 0.825, so the relative difference is about the same, don’t you think?

    I forgot to comment on this, but yeah, you’re right. That’s what I get for doing this after only having a few hours of sleep. πŸ˜›

Leave a Reply

Your email address will not be published. Required fields are marked *