Zend Framework: Slow automatic view rendering

Monday, March 29. 2010
Comments

So I posted something on Twitter today, which wasn't exactly news to me. I was more or less pointing out the obvious.

From a couple follow-up tweets, I guess, I need to explain more.

The idea

My thesis is that there's a gain in page rendering time when I disable automatic view rendering and use explicit render calls ($this->render('foo');) inside my controllers. And to cut to the chase, there is. On our app, I measured a 12% improvement using Xdebug's profiler — simple before-after-style.

General setup

I've blogged about Zend Framework performance before (1, 2, 3). Our setup is not the average Zend Framework quickstart application. We utilize a custom (much faster) loader (my public open source work in progress), no Zend_Application and explicit (vs. implicit) view rendering. The framework code is at 1.10.2. On the server-side, the application servers are nginx+php(-cgi).

I don't feel like repeating myself and while a lot of issues were already addressed in new releases of the framework, or are going to be addressed in 2.0, the above links still hold a lot of truth or at least inside and pointers if you're interested in general PHP performance (in German).

Code

IMHO, it doesn't really matter how the rest of your application looks like. Of course all applications are different and that's why I didn't say, "OMG my page rendered in 100 ms", but instead I said something like, "we got a 10+% boost". The bottom line is that everyone wants to serve fast pages and get the most out of their hardware but since applications tend to carry different features there really is no holy grail or number to adhere to.

Proposal

I urge everyone to double-check my claim. After all, it's pretty simple:

  1. Setup Xdebug
  2. Profile the page
  3. Restart PHP app server/processes (in case you use APC and/or php-cgi)
  4. Disable automatic view rendering: $this->_helper->viewRenderer->setNoRender(true);
  5. Add render() call: $this->render('foo');
  6. Profile again

... simple as that.

Conclusion

All in all this thing doesn't require too much to follow.

Automatics — such as an automatic view renderer — add convenience which results in rapid development and hopefully shorter time to market. But they do so almost always (give it nine Erlang nines ;-)) at the expense of performance.

Update, 2010-03-20 21:37: As Rob pointed out, there's even more to gain by bypassing the helper entirely. Use the code snippet below, or consider something like the following:

Padraic also blogged extensively on Zend_Controller_Action_Helper_ViewRenderer, I recommend reading Having a bad ViewRenderer day in your ZF app?.

Defined tags for this entry: , ,

PHP parse errors with cgi and nginx

Monday, March 15. 2010
Comments

So for whatever reason, it took me a while to figure this out earlier today:

2010/03/15 15:44:16 [info] 22274#0: *148224 client closed prematurely connection, so upstream connection is closed too while sending request to upstream, client: a.a.a.a, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/tmp/.fastcgi.till/socket:", host: "localhost"
2010/03/15 15:44:16 [info] 22274#0: *148207 client closed prematurely connection, so upstream connection is closed too while sending request to upstream, client: a.a.a.a, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/tmp/.fastcgi.till/socket:", host: "localhost"

The issue was a PHP parse error which I overlooked when I added a new file. The weird thing is, I had nothing in the logs (E_ALL, display_errors is off, but all logs are enabled and I tailed them using multitail) and nginx only displayed a blank page. The errors above were in nginx's own log file.

Defined tags for this entry: , ,

DB_CouchDB_Replicator

Wednesday, March 3. 2010
Comments

Update, 2010-03-04: I just rolled a 0.0.2 release. In case you had 0.0.1 installed, just use pear upgrade-all to get it automatically. This release is trying to fix a random hang while reading documents from the source server.

I also opened a repository on Github.

---

As some may have guessed from a previous blog post we are currently running a test setup with CouchDB lounge. My current objective is to migrate our 200 million documents to it, and this is where I am essentially stuck this week.

No replication, no bulk docs

The lounge currently does not support replication (to it) or saving documents via bulk requests, so in essence migrating a lot of data into it is slow and tedious.

I have yet to figure out if there is a faster way (Maybe parallelization?), but DB_CouchDB_Replicator is the result of my current efforts.

I think I gave up on parallelization for now because it looked like hammering the lounge with a single worker was already enough, but generally I didn't have time to experiment much with it. It could have been my network connection too. Feedback in this area is very, very appreciated.

DB_CouchDB_Replicator

DB_CouchDB_Replicator is a small PHP script which takes two arguments, --source and --target. Both accept values in style of http://username:password@localhost:port/db and attempt to move all documents from source to target.

Since long running operations on the Internet are bound to fail, I also added a --resume switch, and while it's running it outputs a progress bar, so it should be fairly easy to resume. And you also get an idea of where it's currently at and how much more time it will eat up.

These switches may change, and I may add more — so keep an eye on --help. Also, keep in mind, that this is very alpha and I give no guarantees.

Installation

Installation is simple! :-)

apt-get install php-pear
pear config-set preferred_state alpha
pear channel-discover till.pearfarm.org
pear install till.pearfarm.org/DB_CouchDB_Replicator

Once installed, the replicator resides in /usr/local/bin or /usr/bin and is called couchdb-replicator.

Fin

The code is not yet on github, but will eventually end up there. All feedback is welcome!

Defined tags for this entry: , , ,

Quo vadis PEAR?

Wednesday, January 27. 2010
Comments

To PEAR or not to PEAR — PEAR2 is taking a while and I sometimes think that everyone associated with PEAR is busy elsewhere. Since a little competition never hurt, I'm especially excited about these recent developments.

With the release of Pirum, I'm really excited to see two public PEAR channels that aim to make PEAR a standard to deploy and manage your applications and libraries. One is PEARhub and the other is PEAR Farm. I think I'm gonna stick with PEAR Farm for a while, so this blog entry focuses on things I noticed when I first played with it.

PEAR vs PEAR Farm

A lot of people mistake these new channels for the wrong thing. They think that this will eventually replace PEAR. I don't think it will — ever.

While I really welcome the idea that people push PEAR's channel for a standard to distribute apps and libraries (PHPUnit, ezComponents, Zend Framework, Symfony, etc.), it's also very obvious that these open channels will never be the same.

For an idea of what I mean — take a look at open code repositories around the web and especially when it comes to PHP, it's very obvious that while there's a lot of code, most of it is utter crap. (There I said it!)

And no one wants to rely on it when reliability is an objective.

The PEAR Coding Standards were not invented because it's so great to tell people how to write code. But a lot of people need this guidance. While they have a lot of ideas about how to implement a feature or a cool algorithm, their passion does not extend to test coverage or even little documentation. And that's where these sometimes frowned upon coding standards come in handy because they ensure that the code in PEAR is maintainable — which is really just the tip of the ice berg for professional software engineers and I'll save the rest for another blog post.

Let's get to it

Regardless of the fact that there always only few steps, PEAR setups tend to not work for or look complicated to a lot of people. Here are a few tips on how to get started. We'll assume pear itself is installed (apt-get install php-pear).

PEAR Farm

Instead of what is written in the FAQ - suggested steps to get started. ;-)

  • pear channel-discover pearfarm.pearfarm.org
  • pear install pearfarm.pearfarm.org/pearfarm-beta

Spec files and package.xml

The package.xml is a configuration file for the PEAR package. It's pretty long, and since XML is so verbose, it's a turn off to many. PEAR Farm suggests to create a spec instead, so it can create a package.xml for you. This is pretty convenient, but there are also a few gotchas.

  • pearfarm init (inside the code repo)

If you're doing it for the first time, it will issue a warning about a configuration file being created — ignore it and move on.

Continue by editing the .spec file with description, summary, maintainer and whatever else is a suggested edit inside it.

Then, feel free create a package.xml:

  • pearfarm build

This will leave you with a package.xml file in the same directory. Mission accomplished!

Gotchas & Tricks

These are a few things you should edit before you pearfarm push:

  • If you use git and happen to have a .gitignore, pearfarm will add .gitignore to the package.xml as well.

  • pearfarm adds a baseinstalldir attribute to the top most <dir /> entity. Assuming your package is Foo_Bar and you have Foo/Bar.php in your repository, it would install into /usr/share/php/Foo_Bar/Foo/Bar.php, instead of Foo/Bar.php. I'd suggest you remove it and instead namespace in the package name right away — YourName_FooBar.

  • Does it work? Always pear package-validate before you push!

  • Does it install correctly? Feel free to pear install Package-x.y.z.tgz and check if the files installed ok (pear list-files pearfarm.pearfarm.org/Package)

  • A package.xml can have files with different roles, while the standard is php, there's also doc (for documentation) and test for tests. When the package.xml is generated from the .spec, all files get php by default, that's why I'd go through the list in <contents /> to double-check that all files have appropriate roles set.

  • Another thing to take care of (imho), would be <dependencies /> — something that could probably be automated, but otherwise read up about in the manual.

  • Need to rebuild the package from your updated package.xml? Use: pear package!

  • Changelog? Why yes, you can! The package.xml supports it and it would be nice if PEAR Farm eventually displays it. Here's how (after <phprelease />):

    
        
          0.0.2
          alpha
          2010-01-29
          bugfix in makeRequest() (curl), corrected endpoint
        
        
          0.0.1
          alpha
          2010-01-27
          initial release
        
    

Most of these things could be improved in pearfarm. and i'm pretty sure they will. Eventually! :)

The End

And that's all for this time. If you want to see my packages on the PEAR Farm, follow this link.

Defined tags for this entry: ,

Wieso zum Teufel benutzt DU keine Versionskontrolle?

Tuesday, January 5. 2010
Comments

(This post is entirely in German, I'll see if I can translate this rant later.) Also, Prost und frohes Neujahr — ich starte das neue Jahr damit etwas emotionalen Ballast aus dem alten Jahr loszuwerden!

Ab und an treffe ich wieder auf Kunden und Kollegen mit denen ich vor relativ langer Zeit — fünf oder sechs Jahren oder länger — zusammengearbeitet habe.

Die Zeitspanne ist deshalb wichtig weil ich generell daran Interesse habe immer wieder oder zumindest des öfteren mit jemandem zusammenzuarbeiten, wenn die Zusammenarbeit erfolgreich war. Wenn es allerdings Zwangspausen zwischen Projekten gibt, dann kann sich der geneigte Leser vorstellen, dass das letzte Projekt nicht vollkommene Zufriedenheit auf beiden Seiten ausgelöst hat.

Nichts desto trotz gibt jeder dem anderen eine neue Chance, und die Bezahlung spielt dann nicht eine gerade untergeordnete Rolle. Einige nennen so etwas Schmerzensgeld, und so ähnlich ging es mir auch in diesem Fall. Bzw. waren meine Motivation Weihnachtsgeschenke für Familie und Freunde, eine PS3 Slim und diverse andere Annehmlichkeiten.

Zwischenmenschliche Beziehungen

Schlußendlich entwickeln Menschen sich immer weiter. Diese Entwicklung merke ich nicht nur an technischen Fähigkeiten und Details, sondern auch menschlich, oder wie heisst so schön — am Stil.

Wenn ich mir nicht sicher bin, dann stelle ich mir folgende Fragen:

  • Wie laufen die Projekte ab?
  • Wieviel Spass macht es allen beteiligten?

Ausnahmen bestätigen die Regel und ab und an dauert die Entwicklung länger und ich muss Überzeugungsarbeit leisten.

In solchen Situation höre ich Sätze wie zum Beispiel:

  • "Aber das mach ich schon immer so."
  • "Objekte, wozu soll das gut sein? Kannst mir auch nen Array geben?!"
  • "Tests. Sowas mach ich nicht."

… oder mein absoluter Lieblingssatz:

  • "Versionskontrolle — das brauch ICH nicht."

Und irgendwann geht's natürlich schief.

Die Versionskontrolle

Besonders der letzte Satz hat es mir angetan und mich tatsächlich nach zwei Wochen Urlaub, nach denen mich wirklich nichts erschüttern konnte, während der Feiertage etwas auf die Palme gebracht.

Denn natürlich lief das Projekt nicht ganz so zügig und wurde nicht pünktlich zu Weihnachten fertig. Und da im neuen Jahr alles funktionieren soll, wurde es etwas hektisch!

Auf meine Frage welche (nicht ob) Versionskontrolle er benutze, erklärte mir der Kollege am Anfang ganz stolz, dass er alle Daten in mehren Kopien vorhät. Beim Kunden ("Produktivsystem") und auf seinen beiden Rechnern. Natürlich fällt einem dabei auf, dass die Versionskontrolle etwas missverstanden wird — denn primär geht es nicht um Backup.

Aber wieso man diesen Stress macht und nicht an einen Dienstleister wie github oder unfuddle auslagert, das ist mir ein Rätsel. Denn natürlich sollte auch die Versionskontrolle gesichert werden.

In dieser Situation fragte ich mich nur wie ein Team zusammenarbeitet, wenn es ohne VCS auskommen muss. Inzwischen kann ich es mir eigentlich gar nicht mehr vorstellen.

Als Argumente für den Einsatz einer Versionskontrolle führte ich an, dass es (eigentlich auch allein Sinn macht — Dokumentationszwecke — und) ab zwei Arbeitern nicht nur viele Vorteile mitsichbringt sondern ein Muss ist, und eine Voraussetzung dafür, dass ich an diesem Spiel teilnehme.

Ich erinnere mich oft an Projekte in dem Mitglieder des Teams mehr als einmal den Stand des anderen überschrieben haben. Für mich reicht das, aber anscheinend ist so etwas nicht abschreckend genug. Zu oft müssen Entwickler mit Code umgehen und wissen nicht wieso ein Problem auf diese und nicht jene Art gelöst wurde — bei richtigem Einsatz der Versionskontrolle (und Dokumentation im Code) passiert so etwas nicht.

Am Ende einigten wir uns auf git und ich kaufte dafür bei Github ein — und es ging los.

Im Projekt

Rückschläge gab es.

Mein Kollege besitzt zum Beispiel noch das selbe Notebook wie vor sechs Jahren. Und das hatte er gerade mit Windows XP neu eingerichtet. Und Git unter Windows war ihm zu mächtig ("das schreibt sich sicherlich überall in die Registry rein") wodurch er auch nie die Versionskontrolle dabei hatte.

Obwohl ich ihn mehr als einmal gebeten habe zumindest während unserer Zusammenarbeit git auf seinem Laptop aufzusetzen, hat er es dann doch nicht geschafft.

Besonders zeitraubend ist es, wenn der aktuelle Stand per Email oder per USB-Stick ausgetauscht wird. Manuelles mergen gehört zu den Dingen die ich überhaupt nicht machen möchte und generell lehne ich es auch ab meine geänderten Dateien per Email wieder zurückschicken.

Wieso auch, wenn alles mit git commit, git push und git pull erledigt werden kann?

Aber natürlich haben wir genau diese Dinge zwischen Weihnachten und Neujahr getan.

Die Ironie und Absurdität dieser Situation ist bezeichnend.

Fazit

Liebe Kinder!

Bei der Arbeit könnt Ihr wirklich am meisten Zeit vergeuden und alle in den Wahnsinn treiben wenn Ihr keine Versionskontrolle einsetzt.

Denn bei konsequenter und halbwegs gescheiter Benutzung würden folgende Fragen entfallen:

  • "Wieso sieht das so aus?"
  • "Hatten wir das nicht schon mal?"
  • "Welche Dateien hast Du gerade bearbeitet?".
  • "Kannst Du mir das mal eben schicken?"
  • "Das hab ich doch gestern schon gemacht?"
  • "Hast Du eben die Datei x überschrieben?"

... und mir würden noch andere einfallen, aber irgendwann muss auch mal Schluß sein.

The End

Keine Versionskontrolle — das hab ich lange nicht erlebt aber vielleicht ist das bezeichnend für die PHP-Welt. Ich würde auch zu gern noch einen Absatz über's Testen schreiben, denn auch darauf haben wir konsequent verzichtet.

Und es gab zu viele gute Beispiele wo es sinnvoll gewesen wäre. Aber das hebe ich mir für einen anderen Tag auf! :-)

Defined tags for this entry: , , , ,