Archive for the 'php' Category


Pressing WordPress 14

This post is designed to inspire our beloved server administrator to get some sort of caching installed.

So I finally decided that enough was enough and I wasn’t going to wait until I spontaneously combusted with the motivation to build my own blogging/CMS system and finish my site. Last night I downloaded WordPress and began hacking my design into their template framework.

While testing it all out, I noticed that the responses seemed pretty slow. I wasn’t sure if it was the wireless network (I’d been wrangling with it a few hours earlier), so this evening I decided to do some benchmarking. I am something of a performance freak, after all. (So I lied about my intentions at the beginning of the post… who cares?) I’d already looked at some of the code (quite hideous, in my personal opinion), so I had a feeling things wouldn’t be pretty out of the box.

I was right: the default installation managed a measly 4 requests per second. First I installed APC, which, under Ubuntu, requires installing the PEAR and php5-dev packages, then running sudo pecl install apc. The addition of byte-code caching pushed it up to 13 requests/second. Clearly, the code was suffering from runtime — not compilation — issues.

I didn’t have any real desire to delve too deep into the code, so I opted for the prebuilt WP-Cache plugin. And this one was worth the money: just by enabling the plugin I jumped to nearly 500 requests/second. Note that this is a 125 times better than I started with. (Out of curiosity, I also ran with caching on and APC off; about 200 requests/second.)

In short: if you’re running WordPress and you can/have self respect (*grin*), install APC and WP-Cache.

Emerging XDebug 2.0.0 0

XDebug has finally (after ~4 years, according to their website) gone 2.0. Unfortunately, there’s no ebuild for the new version in Gentoo’s Portage. Luckily, they’re really easy to create, as all you have to do is change the name of the file.

The only trick, however, is that you’ll want to set it up in a portage overlay. But this is easy to setup, too.

Creating an Overlay

I created my overlay in /usr/local/portage; it gives me a convenient place to store hacked up ebuilds (like this one). First, create the directory:

# mkdir /usr/local/portage
# cd /usr/local/portage

Now you need to add this directory to the PORTDIR_OVERLAY variable in /etc/make.conf. Multiple values are separated by spaces.

Building the eBuilds

# cd /usr/local/portage/
# mkdir dev-php5
# cd dev-php5
# mkdir xdebug
# cp /usr/portage/dev-php5/xdebug/xdebug-2.0.0-rc4.ebuild ./xdebug-2.0.0.ebuild
# ebuild ./xdebug-2.0.0.ebuild digest

It also depends on your xdebug-client package being the same version, so create one of those as well:

# cd /usr/local/portage/
# mkdir dev-php
# cd dev-php
# mkdir xdebug-client
# cp /usr/portage/dev-php/xdebug-client/xdebug-client-2.0.0-rc4.ebuild ./xdebug-client-2.0.0.ebuild
# ebuild ./xdebug-client-2.0.0.ebuild digest

Done

And now you should be ready to emerge the package like usual!

Including benchmarks 3

As part of the namespace discussion, the performance difference between including multiple files and concatenating those files into a single file, mainly because of the aforementioned limitation.

In response to an argument for concatenation, Rasmus Lerdorf (original author of PHP) said:

Note that what you are saving by combining the files into one is just a single stat syscall per file. And that can be alleviated by setting apc.stat=0 in your config. That of course means you need to restart your server or flush your cache whenever you want to update the files. In apc.stat=0 mode you gain nothing by merging all the files.

Now, I’d always theorized that concatenation could a present measurable performance increase, so I was a little muffed by this statement. Consequently, I ventured forth to prove this out.

Setup

First, I generated 100 files each containing a single class. The files and classes were named consecutively, 1-100. I then created one script that dynamically included each file, another that statically included each file, and one that contained all of the files concatenated together. I used Apache Bench and had APC enabled. I ran one set of tests with apc.stat=0 and one with apc.stat=1. The tests were run on a AMD Sempron 2600+ with 512MB of RAM, running Apache 2.0.58 with mpm-prefork and PHP 5.1.6.

Results

I was a little surprised by the results. Because they were better than I’d ever theorized: even with apc.stat=0, the concatenated file request times were less than half those of the static list.

Dynamic

Requests per second:    247.86 [#/sec] (mean)
Time per request:       40.346 [ms] (mean)

Static

Requests per second:    279.86 [#/sec] (mean)
Time per request:       35.732 [ms] (mean)

Concatenated

Requests per second:    605.07 [#/sec] (mean)
Time per request:       16.527 [ms] (mean)

Also of note: the dynamic includes didn’t really lose by much to the static includes. That should make people using __autoload (like me, at work) happy (it does).

Apparently, there’s still some performance to be gained by concatenating your libraries into a single file, even with a byte-code cache. Now, granted, you may not always include 100 files, or your entire library. However, by analyzing your usage patterns, you could always create a single file containing the classes you use the most, and leave those only occasionally used to your autoload implementation.

Solving the wrong problem 0

I’m going to apologize in advance for bringing this up again, but there’s been more talk on the php.internals list about the namespace patch that was applied to PHP 6. And somewhere in the discussion (erm, I think discussion implies that there are two opinions given equal weight), someone linked to the original post that started this round.

Main assumption of the model is that the problem that we are to solve is the problem of the very long class names in PHP libraries.

Suddenly, I realized what was wrong: they set out to solve the wrong problem!

Namespaces reduce typing? No. Namespaces allow the same symbol to be used in two contexts. Importing a namespace, thereby saving keystrokes, is just a nice (and popular) addition.

I’m not giving up hope, though. Maybe, just maybe, one of us will cut through the fog.

PHP4 is dying 2

About 11 days ago now, Derick Rethans (author of the wonderful XDebug, among other things) broached the topic of dropping support for PHP 4 at the end of the year on the PHP internals mailing list. Seven days and approximately 165 replies later (record time for the internals list, if you ask me), an announcement was posted on php.net.

As a developer working for a company that bemoans the fact that we still have one legacy application running under PHP 4 (and only on the server; it’s running under 5 on our workstations), I thought nothing of the announcement. I definitely didn’t expect the uproar that it’s apparently caused. Perhaps the most visible complaint so far: the author of WordPress.

PHP 5 has been, from an adoption point of view, a complete flop. Most estimates place it in the single-digit percentages or at best the low teens, mostly gassed by marginal frameworks.

Again, my view of the transition has been skewed, so I can’t even relate to the above statement. In either case, it’ll be interesting to see how PHP 4 projects react.

Namespaces++ 4

PHP 6 now has namespace support checked into CVS. Unfortunately, they opted for the easy route: a single namespace construct at the top of a file declares the namespace for everything contained within that file. In other words, completely contradictory to every other construct in the language. It also limits you from ever using two namespaces within the same file. And all for no good reason. I even got involved and posted to the php.internals mailing list (unsurprisingly, with little, if any, effect).

</rant>

MySQL Compression 6

There are a lot of instances where it’s extremely convenient to blobs of data in a MySQL database. It’s not necessarily the most efficient storage, but it definitely has convenience points.

Speaking of convenience, MySQL actually includes compression functions that you can use right in your queries, allowing you to store the data compressed, but sill have introspection abilities without any special interface. Unfortunately, however, those functions aren’t directly compatible with, say, the PHP gzip extension, so you’re stuck packing all of the compression load on your perhaps already overloaded database.

That is, until now. A few days ago I was facing this exact problem at work, and with a little goading from the DBAs (i.e., they said it was “impossible”), I determined that I’d fix it, regardless of what it took.

After a few skinny dips into both the MySQL and gzip-extension source code, I discovered that MySQL was prepending a long integer onto the beginning of the compressed string. Luckily, this is easy to replicate in PHP:

<?php
// compress compatible with MySQL UNCOMPRESS(...)
$compressed = pack('L', strlen($string)).gzcompress($string);

// uncompress compatible with MySQL COMPRESS(...)
$uncompressed = gzuncompress(substr($compressed, 4));
?>

Compression for all!

Certifiable 1

Back in May I had the opportunity to attend the php|tek ’07 conference that was put on by php|architect magazine. They included a complimentary Zend Certification Exam, which, of course, I took advantage of. I found out the other day (only about a month later!) that I’d passed. I guess I’m now official.

Before taking the test I was required to sign a bulletproof non-disclosure agreement and swear on a stack of Bibles that I wouldn’t divulge any of the contents, so I won’t say much. However, being a self-developed developer from the very beginning, I always knew that a piece of paper with a shiny seal wouldn’t change a single thing: I was either a good developer, or I wasn’t, certified or not. Taking the test only served to make me more aware of that.

So while I’m sure it’ll look pretty on my resume, I’m just not that excited.

« Previous Page