Paul M. Jones

Don't listen to the crowd, they say "jump."

A Siege On Benchmarks

My regular readers (and perhaps the irregular ones as well ;-) know that I have been obsessed with baseline-responsiveness benchmarking of frameworks for years now.  The idea has always been that, in order to know how far you can optimize your framework-based applications, you need to know the limits imposed by the framework itself.  Only then can you have an idea of where to spend your limited resources on improvement.  For example, if you need 200 dynamic requests/second, but the framework itself (with no application code in use) is capable only of 100, then you know that no amount of application or database optimization will help you -- it's time to start scaling, either horizontally or vertically.

To perform these benchmarks, I have only employed the ab tool provided by the Apache web server.  It was easy to use, and relatively easy to parse the output to automate reporting.  However, it turns out that ab over-reports responsiveness of Apache when serving static HTML files, and when serving minimal PHP scripts such as <?php echo "hello world"; ?>.  I discovered this just recently when attempting to find out why PHP appeared to be faster than HTML, and then only with the assistance of Paul Reinheimer, whom I now owe a bottle of vodka for his trouble.  ;-)

It turns out that the siege tool from JoeDog Software is more accurate in reporting static HTML and PHP responsiveness.  This is confirmed through Paul Reinheimer as well, who reported the expected responsiveness on other systems.

The over-reporting from ab means that all my previous reporting on benchmarks is skewed too low when comparing framework responsiveness to PHP's maximum responsiveness.  As such, I have re-run all the previously published benchmarks using siege instead of ab.  Previous runs with ab are here ...

... and below are the updated siege versions.  As with previous attempts, these benchmarks are performed on an Amazon EC2 "small" instance.  There is one difference to note: previous runs used Xcache for bytecode caching, but these use APC; I don't suspect this change in caching engines has a significant effect, but I have not tested that assertion.

framework rel avg
baseline-html 1.1878 985.69
baseline-php 1.0000 829.82
cake-1.1.10 0.0938 77.84
cake-1.1.11 0.1277 105.96
cake-1.1.12 0.1288 106.84
cake-1.1.16 0.1166 96.77
cake-1.1.17 0.1165 96.70
cake-1.1.19 0.1298 107.69
cake-1.2.0-rc2 0.0516 42.79
solar-0.25.0 0.1852 153.66
solar-0.26.0 0.1789 148.43
solar-0.27.0 0.1734 143.93
solar-0.28.0 0.1671 138.64
solar-1.0.0alpha1 0.1706 141.58
symfony-0.6.3 0.0629 52.22
symfony-1.0.0beta2 0.0758 62.91
symfony-1.0.6 0.0746 61.91
symfony-1.0.6-dw 0.0820 68.03
symfony-1.0.6-fp 0.0853 70.78
symfony-1.0.17 0.0744 61.73
symfony-1.1.0 0.0745 61.84
zend-0.2.0 0.2176 180.56
zend-0.6.0 0.1998 165.78
zend-1.0.0 0.1268 105.25
zend-1.0.1 0.1263 104.80
zend-1.5.2 0.0951 78.93

Note the baseline-html and baseline-php numbers.  Using ab previously, these were reported as 2100-2400 requests/second and 1100-1400 requests/second, respectively.  The siege tool reports a much lower number for both, but the dropoff between static HTML and dynamic PHP is much smaller; with ab it looked like about 40-50%, but now with siege it looks like only about 15-18%.  This behavior is much more like what we would expect from a memory-based PHP script.

Note also the separate framework requests/second; they are very similar between ab and siege.  This means that the framework responsiveness numbers are almost unchanged.

Because the nearly-identical framework numbers are compared to a much smaller baseline PHP number, the frameworks now appear to be doing much better in relation to PHP's maximum responsiveness.  For example, Solar-1.0.0alpha1 with ab appeared to run at about 11% of PHP's max, but with siege it looks close to 17%.  All of the frameworks tested see this kind of comparative gain in their reporting.

However, when compared to each other, the framework rankings are the same as before:  Solar has the highest baseline responsiveness, followed by Cake and Zend (their respective releases are very close to each other in responsiveness), and Symfony trails with the lowest baseline responsiveness.

In summary, using ab skewed the "percentage of PHP" comparisons because it over-reported PHP's maximum responsiveness, but the framework requests/second numbers and the framework comparative rankings are unchanged from previous reporting.  The Google project for the benchmarking system has been updated to use siege, so all future reporting will reflect its results, not those of ab.


Lazyweb Request: Why would PHP be *faster* than HTML?

With the help of the great guys at Slicehost.com, I am attempting to run my benchmark series on a virtual private server, to compare with EC2. However, I'm seeing a very strange result for the baselines: a PHP page delivers more requests-per-second than a static HTML page.

The OS is a stock Ubuntu 8.10 installation; you can see the setup steps here.

The virtual private server has 2 gigs of RAM, and is on a box by itself, so there is no other external activity to skew the results.

I ran ab -c 10 -t 60 http://localhost/ on each of two files: index.html, which has only the static text "hello world"; and index.php, which has only the code <?php echo 'hello world'; ?>.

Here are the results without APC, averaged over 5 one-minute runs:


index.html : 7067.57 req/sec
index.php  : 7484.57 req/sec # faster???

Here are the results with APC, averaged over 5 one-minute runs:


index.html : 7013.50 req/sec
index.php  : 8041.06 req/sec # faster???

I haven't seen this behavior on EC2. I'm not complaining, but it does seem unintuitive; invoking the PHP interpreter should be more expensive than just delivering a static HTML file. Does anyone have ideas as to why this might be happening?

UPDATE: With the help of Paul Reinheimer, we appear to have found the culprit: the ab tool itself seems to be at fault. Running similar tests by hand with siege returns much more reasonable and expected numbers (~4000 req/sec for HTML, ~3200 for PHP). I'm going to re-work the test scripts to use siege later and report back. Thanks to everyone who provided suggestions, and special thanks to Paul Reinheimer for working through it with me today.


Fundamental Error in the So-Called "Stimulus" Approach

Congressmen, Senators, the President, and all the high advisors feel that "we need to do something!" about the current economic crisis. Leave aside that government action is at least 50% the reason we got into this mess (I'd rate it closer to 80%). These guys are succumbing to a major critical-thinking error:

1. We must do something!

2. This (the so-called "stimulus" package) is something.

3. Therefore, we must do this.

Merely that it's something to do doesn't mean it's a good idea.

I'd rather seem them subscribe to this: "Don't just do something -- stand there!" Government doing *nothing* is almost always much better than government doing *anything*.


Say "No" To Smarty!

I just discovered nosmarty.net in my Solar referrer logs. I have little love for Smarty, so it's nice to see this:

First released in January 2001, Smarty has become a stagnant, bug-ridden mess--and also the most popular PHP templating engine in use today. But it shouldn't be. No Smarty was created to warn developers about its use and encourage the use of superior alternatives.

Hey guys, you might want to add Savant to your list of PHP5 alternatives. Aside from that, great site!

UPDATE: To those who think my tone is inappropriate -- "I'm not disrespectful, I'm just ahead of the curve." </joker> ;-)

UPDATE (Thu 05 Jan): Please note that I am not affiliated with nosmarty.net in any way. I just saw it in my referrer logs and linked to it in this post. Thank, Ivo Jansch, for pointing out the need for clarity here.

UPDATE (Thu 05 Jan 10:56): A commenter below opines "If Smarty is used in the right manner, I don't see why it can't have it's place within the arsenal of tools for developers to use." I respond that there *is* no right manner in which to use Smarty; it's solving the wrong problem. I expound on that here:

You may have heard that you need to keep your PHP and HTML separated, but that’s not quite the case. Instead, what you need is to keep your "business logic" separate from your "presentation logic", and that’s a different thing entirely.

Thus, all that’s required is a way to keep your views and controllers separated, and perhaps provide helpers for common view tasks. Then you can use plain PHP in your view scripts (templates), without needing a whole new language.


Updated "Getting Started" Docs for Solar

In a long, long overdue move, I have updated the old "Getting Started" docs for Solar.

  1. First Run (how to download and install a Solar system)
  2. First Vendor (creating your own workspace in the system)
  3. First Basic App (short CLI command to create app class files)
  4. First Model (short CLI command to create model class files)
  5. First Model App (short CLI command build a BREAD app based on a model)

My apologies to everyone who hit the brick wall of the bad old docs; their continued existence was nobody's fault but mine. Special thanks go out to Anthony Gentile at OmniTI, whose experience with the previous documentation embarrassed me into writing these new, much easier getting-started guides.


The Framework as Franchise

My PHP Advent article is up; therein I try to describe the parallels between public frameworks and business franchises. However, the PHP Advent site doesn't support comments; if you would like to comment, please do so on this blog post instead. Thanks!


Patterns of Intellectual Bullies

This post is in response to http://terrychay.com/blog/article/challenges-and-choices.shtml, specifically this part:

When people put "design patterns" on their resume, I like to ask them a particular question -- especially when their background is J2EE or they say they know design patterns. The question I like to ask is define design patterns -- what does that term mean? I’d say about 90% of the people who put that on their resume bomb that question. It’s actually not an easy question. As soon as they answer it -- they give me some sort of pseudo-book definition -- I tear into them. I’ll give you an example:

The typical thing that they’ll say is, "Oh! A design pattern is this code thing that solves...umm...a problem."

And I’ll go, "Well, shit." laughter "Quicksort, right? That must be a fucking design pattern then." laughter

And then they’ll say, "Well no. Quicksort isn’t a design pattern."

Then I’m like, "Well, explain to me how it isn’t a design pattern. Your definition is that is solves a problem -- which I agree, design patterns do solve a problem -- but obviously that’s not a sufficient definition for design patterns."

You get where I’m coming from? And the reason isn’t...

And then they’ll say something like, "Well, you know. It doesn’t have like... It’s not an algorithm!"

"Umm...Yeah. So then design problems are something that solves a problem but isn’t an algorithm. So, code versioning! The practice of code versioning solves a problem and it’s not an algorithm clearly! (In fact this is what’s called a "best practice.") So how is a best practice not a design pattern?"

See no matter what they do they fall in a fucking trap. laughter

So I’ll give you my definition of design patterns. Well my honest-to-goodness definition of design patterns is to quote a famous Supreme Court justice when he was talking about it: He said that he’ll know it when he sees it.

Actually, he was talking about porn. laughter But there is pretty much no difference between design patterns and porn so we are all okay with that.


For Terry to say "design patterns are like porn, you know it when you see it" is funny and entertaining, but careless and unhelpful.

When a web developer talks about design patterns, it seems likely he means patterns of the type described by Martin Fowler in "Patterns of Enterprise Application Architecture". Regarding the definition of patterns, Fowler has this to say on page 9:

There's no generally accepted definition of a pattern, but perhaps the best place to start is Christopher Alexander ... "Each pattern describes a problem which occurs over and over again in out environment, and then describes the core of the solution to that problem, in such a way that you can use this soution a miillion times over, without ever doing it the same way twice."

Fowler then goes on for several paragraphs refining and explaining the concept. So while nobody has a rigourous definition of "design patterns", there does appear to be a rough outline of how to discover them, and then to agree on instances of patterns by naming and describing them. (Whereas the definition of porn cannot ever be agreed on, becuase it is in the eye of the beholder. I'd prefer not to take the analogy much further. ;-)

Patterns as Domain-Specific Vocabulary

Fowler (page 11) says "... the value of the pattern is not that it gives you a new idea; the value lies in helping you communicate your idea." That is, patterns are a common vocabulary to aid communication. Application design patterns are a vocabulary to aid communication about application design.

There are many kinds of patterns in the software world. To use Terry's examples, quicksort could easily be called a pattern of some kind, perhaps a sorting pattern. Code versioning could also be called a pattern of some kind, perhaps an organizing pattern. Best practices might be patterns of management. But they're not application design patterns.

Intellectual Bullying

As the interviewer, Terry does not appear to be seeking to tease out what the applicant thinks he means when he says "design patterns". Terry uses the term "design patterns" in a generic way, instead of in the way the applicant most likely intends -- "application design patterns". It sounds like Terry is attempting to trap the interviewee by subtly and purposely misleading him.

I have to wonder if that kind of questioning technique is appropriate behavior for someone in a position of power (and the interviewer does have a measure of power over the applicant). It sounds like an intentionally negative experience, one that is unnecessarily humiliating.

In fact, it sounds like bullying; intellectual bullying, to be sure, but bullying nonetheless. It reminds me of passages from the chapter on "Homo Logicus" in Alan Cooper's "The Inmates Are Running The Asylum". Cooper (101-104) compares and contrasts the physical/athletic jock and the mental/intellectual jock, both of whom exhibit immature bullying behavior.

The athlete bully, with great physical prowess, begins with the idea that "If I can beat you in a physical contest, then I am your master and I am better than you," but eventually is conditioned to accept that physical domination is not socially acceptable. He grows up when he realizes he can't get along with other adults by bullying them.

The intellectual bully, with great mental prowess, begins with the idea that "If I can beat you in a mental contest, then I am your master and I am better than you." However, the intellectual bully rarely learns that mental domination is similarly unacceptable in civil, adult discourse. "There is no maturation process to temper their exercise of that power." (Cooper, 104)

Closing Thought

When in a competition, physical or mental, try to win! But civil discourse is not competitive; you don't "win" a conversation. Mature adults attempt to work with each other to clarify meaning; they are both truthful and helpful when speaking to each other. They try to "find out what is right." Bullies and the immature, on the other hand, want to "be right" period, even if (maybe even because) that means knocking the other person around. Beware the mental bully in yourself, and point it out when you see it in others.



Escape from Namespaces

I admit that I am an unproductive whiner on this issue. I don't care if namespaces go into PHP or not; at this point, I'd almost rather they not. But some of my feelings as expressed on IM this morning:


09:13:08  pmjones: yayfornewnamespaceseparator
09:13:12  pmjones: hmmmm
09:13:19  nate: oh geez
09:13:27  nate: I can't believe they picked *that* one
09:13:33  pmjones: does that mean there are two newlines in that phrase?
09:13:36  pmjones: who knows.
09:13:53  nate: you should really post something like that
09:14:01  pmjones: maybe PHP really *is* getting bought by Microsoft
09:14:12  nate: yeah
09:14:17  nate: you'd have at least thought they'd go with /
09:14:31  pmjones: no, that's division
09:14:38  pmjones: which might make sense, now that i think about it
09:14:47  pmjones: for all the divisiveness we have over it
09:14:51  nate: heh ;-)
09:14:59  nate: you took the words out of my mouth
09:15:03  nate: er, fingers
09:15:06  pmjones: indeed
09:15:16  pmjones: i know you want namespaces very badly ...
09:15:23  pmjones: ... but do you want them *this* badly?
09:15:45  nate: still undecided
09:16:00  pmjones: if you want them badly, badly is what you've got ;-)

To explain the jokes:

The "n" characters in the namespace string are escaped newlines; thus, "yayfornewnamespaceseparator" might well be translated as "yayfor[newline]ew[newline]amespaceseparator". ASCII gurus will know what f and s translate to.

Zend Is Not PHP, so Microsoft can't buy "PHP". But the backslashes are very DOS-ish.

Here ends the unproductive whining, at least for now.


... But Some Suck Less Than Others

(N.b.: This is a post I've had in the queue for several months now, and while I still don't feel like it's "finished", it's time to just publish the thing and be done with it.)

Laura Thomson says that all frameworks suck -- and she's right! But maybe not for the reasons you think.

Before we get started, let me give her a big public thank you for her praise of my benchmarking methodology: thanks, Laura. :-)

Also, let me point out that I am the author of a framework, Solar, and so I am as much an example of the behaviors I describe below as anyone else.

I don't mean to put words in her mouth, but I'd prefer to extend Laura's phrasing a bit. I'd argue that "all frameworks from other people suck". (Cf. Rule Number One from my "obsessive-compulsive sociopath" blog post.)

The "other people" part is important here. It sucks to have to learn how someone else wants you to work, and that's a big part of what a framework needs from you: to learn how to use it. Learning someone else's code is much less rewarding in the short term than writing your own code. I think there's a kind of subjective relativistic effect: time spent learning and analyzing drags out, but code-writing time flies by -- even if it's the same amount of objective time spent. Time-drag sucks.

By definition, this means that the framework you write for yourself sucks less than anything else out there -- it feels more rewarding. Jeffrey Palermo points out another factor: the framework author is his own customer, and has to satisfy only himself (or his team) when writing it.

Even if you are a responsible developer, perhaps because you are one, you probably will build your own framework, and pretty early on at that. You would be a fool not to; if you face the same set of problems over and over, eventually you will settle on a preferred series of solutions. If you write the same code over and over again, from scratch, on each project that solves similar problems, then you're probably not getting the "code reuse" thing yet.

That collection of solutions-in-code is your framework. It may be highly formalized or very loose, highly consistent (or not), and so on. But it is a framework.

And I guarantee there will be things you don't like about that first framework -- so you'll write another one. Maybe even a third, as you continuously internalize the problem sets, because there's no substitute for front-line experience (do all the testing you like, but real-world use will be the truest critic of your process).

Finally, after all your work extracting that solution-in-code, you will want to share your wonderful creation with the world, the True Path that is clearly useful if only others are wise enough to recognize it. And to those great unwashed, who do not recognize all your effort and genius, your framework will suck.

This is because there are quirks and workarounds and hacks that you have internalized and accepted and are so familiar with that you no longer pay attention to them, and they don't make sense to other developers. Even working-style similarities among framework developers and adopters will only reduce, not eliminate, framework suckage. There's always something that could have been done differently -- and many prospective adopters will see that as a reason to build an entire new framework, from scratch, to address those points, because (by definition) their own work sucks less.

Sturgeon's law says 90% of everything sucks, and the development world is no different. Almost nothing is perfect for every developer: there's always significant room for valid criticism on any project, and even the best projects are lacking in at least one vital area (and that area is different for each project).

It's all about tradeoffs between what you want to do and what you are willing to put up with in order to do it -- and at no point will you get everything exactly precisely the way you want, either with a framework or without one. There's no silver bullet. This means that you have to put up with suckage no matter what -- some frameworks suck less than others, is all.

(Personally, I think Solar sucks least; but then, I would say that, wouldn't I? ;-)