Archive for December, 2008

When looking for something in an array of values, it is very tempting to use in_array(). After all, that’s what the name says. However, searching through an array, even with best-case search algorithms, will never be faster than a single index lookup, which is where isset() comes in. With isset(), you can use one operation to see if a value exists, provided those values exist as keys. I don’t know if it’s truly random access, but it’s pretty darn close.

So, instead of something like this:

1
2
3
4
5
6
7
8
9
$exclude = array(1, 4, 6, 8);
 
for ($i = 0, $size = count($data); $i < $size; $i++)
{
   if (in_array($data[$i]['id'], $exclude)
   {
      // do something
   }
}

do something like:

1
2
3
4
5
6
7
8
9
10
11
12
$exclude[1] = true;
$exclude[4] = true;
$exclude[6] = true;
$exclude[8] = true;
 
for ($i, $size = count($data); $i < $size; $i++)
{
   if (isset($exclude[$data[$i]['id']]))
   {
      // do something
   }
}

So does this make a difference? Let’s write a little benchmark script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/php
<?php
$haystack = array();
for ($i = 0; $i < 1000; $i++)
{
    $haystack[] = rand(0, 1000);
}
 
$needles = array();
for ($i = 0; $i < 1000; $i++)
{
    $needles[] = rand(0, 1000);
}
 
for ($i = 0; $i < 1000; $i++)
{
    foreach ($needles as $needle)
    {
        if (in_array($needle, $haystack));
    }
}

We fill two arrays with 1000 random integers. One is the haystack – what we will search through. The other is the list of needles – we want to search for each one. For each needle, we look for it in the haystack. Then, we repeat this 1000 times.

Executing this, the script takes around 37 seconds:

% time ./bench.php
 
real    0m37.400s
user    0m37.282s
sys     0m0.068s

Now, let’s change the last for() loop to this:

15
16
17
18
19
20
21
22
for ($i = 0; $i < 1000; $i++)
{
    $tmp = array_flip($haystack);
    foreach ($needles as $needle)
    {
        if (isset($tmp[$needle]));
    }
}

The new output:

% time ./bench.php
 
real    0m0.778s
user    0m0.764s
sys     0m0.008s

Execution time drops from around 37 seconds to 0.7 seconds.

It’s All About Scope

A while ago, we were struggling with the question of whether or not to use a framework with some new code.  Specifically, did we want to use Zend Framework or not?  (The reasons for settling on ZF vs. others is the topic of a different post.)  We had been using our own little framework for almost a year, and it had served us relatively well.

Reasons to use ZF:

  • Many have worked on it and will continue to work on it, and it enjoys community support. After all, it was created by the PHP people.
  • Why re-invent the wheel?
  • Accelerates development and time to release.

Reasons not to use ZF:

  • It will impact performance. After all, it is plainly more code. The question is how much?
  • There will be a learning curve to learn the “framework” way, when we already know our own code.

My #1 concern was with performance.  So I ran some tests using Apache Bench and Zend Framework 1.0.  I won’t concern you with the details of the test because 1.0 is now a bit outdated, and the performance of Zend Framework is not really the point of this post.  But I will say that ZF was much slower than what we were currently using.

Then I got to thinking about all the websites out there.  Zend is a very nice framework – perhaps my #1 choice for frameworks at the time (though that changes frequently). And getting “Hello World” to work was easy and enjoyable.

But different websites have different audiences. If I am making a local storefront website, or even a chain website, the traffic patterns are going to be very different from a website aiming to be a national destination. If I were cranking out storefront websites every month, I think ZF is the way to go. It’s quick, and I’m sure I would be doing similar things over and over again. ZF is very good for that. Same goes for a shrink-wrap application (by shrinkwrap, I mean something downloadable and installable). If I wanted to make the next great blogging platform, and thousands of people would come to my website just to download it and put on their own hosts, again, ZF is very good for that. (In fact, I would make the application in ZF, and the website to download it from in ZF!)

But for my company, it’s different. If we are to become that national destination that we want to be, it will need every ounce of performance squeezed out. It will have a very custom environment, and require very custom features. That is why Zend Framework, and other frameworks, fail.