Archive for July, 2007

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.

Query Uncache 0

Apparently, in MySQL 5.0.36, there was a bug that prevented INSERT INTO ... ON DUPLICATE KEY UPDATE ... queries from flushing the query cache for the table they were modifying. According to the MySQL manual:

If a table changes, all cached queries that use the table become invalid and are removed from the cache. This includes queries that use MERGE tables that map to the changed table. A table can be changed by many types of statements, such as INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE.

But the evidence speaks for itself:

mysql> insert into sessions values ('fooh', 'blah', now())
  on duplicate key update session_data=values(session_data);
Query OK, 1 row affected (0.00 sec)

mysql> select * from sessions where session_id='fooh';
+------------+--------------+---------------------+
| session_id | session_data | date_modified       |
+------------+--------------+---------------------+
| fooh       | blah         | 2007-07-27 07:41:57 | 
+------------+--------------+---------------------+
1 row in set (0.00 sec)

mysql> insert into sessions values ('fooh', 'blah2', now())
  on duplicate key update session_data=values(session_data);
Query OK, 0 rows affected (0.00 sec)

mysql> select * from sessions where session_id='fooh';
+------------+--------------+---------------------+
| session_id | session_data | date_modified       |
+------------+--------------+---------------------+
| fooh       | blah         | 2007-07-27 07:41:57 | 
+------------+--------------+---------------------+
1 row in set (0.00 sec)

mysql> select sql_no_cache * from sessions where session_id='fooh';
+------------+--------------+---------------------+
| session_id | session_data | date_modified       |
+------------+--------------+---------------------+
| fooh       | blah2        | 2007-07-27 07:41:57 | 
+------------+--------------+---------------------+
1 row in set (0.00 sec)

Now, for us the fix is as simple as adding the SQL_NO_CACHE hint to our queries (or updating our version of MySQL, possibly). And, actually, adding it to the session queries isn’t a bad idea anyways — there’s not really any point in attempting to cache data from a table that gets written to with every page load. This could free up space in the query cache for other data that might have a chance of sticking.

As far as I can tell, this bug was fixed in 5.0.41 (at the latest).

Getting Exaile to sing 0

If you’re wanting to install Exaile on your Gentoo box AND have it play MP3s (and perhaps this goes for all multimedia applications), you’ll want to enable the mad USE flag.

Oh, and so far I’d recommend Exaile if you’re looking for a player that doesn’t come with a lot of baggage — like Gnome/KDE libraries. It’s fitting into my XFCE4 desktop very nicely and has all of the features you’d (or at least, I’d) expect from a player.

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.

MCEGuru 3

MCEGuru is a client/server application that turns your Nokia 770 “internet tablet” into a touch-screen Windows XP Media Center Edition remote. And it looks nice while doing it. In fact, I think this is a 770 killer app.

Be sure and check out the videos; I showed them to a coworker and he placed an order for a 770 within minutes.

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>

Coming soon 1

www.iphonegay.com Coming Soon!

(No, that’s not my domain.)

Next Page »