Friday, December 28, 2012

Top 10 articles 2012

Article Published Views
Using V8 Javascript engine as a PHP extension Jul 22 8458
Create PDF invoices with HTML5 and PhantomJS Dec 8 2006
How to write a really small and fast controller with PHP Jul 17 1320
MySQL or MySQLi or PDO Jul 21 957
PHP Framework Comparison Oct 19 916
Mass inserts, updates: SQLite vs MySQL Sep 13 585
How to implement really small and fast ORM with PHP Oct 16 524
PHP memory consumption with Arrays and Objects Jun 23 465
For or Foreach? PHP vs. Javascript, C++, Java, HipHop Jun 27 444
How to implement a real-time chat server in PHP using Server-Sent Events Oct 29 386

Views from 6/19/12 to 12/28/12: 23464

Top 5 CountryViews
United States4680
United Kingdom1224

Wednesday, December 26, 2012

Building PHP extensions with C++, the easy way (update: MySQL, threads)

Here is an easy way to build a PHP extension with C++ and default PHP packages on a Ubuntu system. I use SWIG to wrap C++ code to the Zend API. When using loops and recursion intensively, porting a few functions to C++ can give you some extra power.

Saturday, December 8, 2012

Create PDF invoices with HTML5 and PhantomJS

Creating invoices in PDF is always a bit tricky: there are many libraries to create PDF documents with PHP, but most can't handle complex layouts and require a lot of memory and CPU time. Things like Unicode characters and line/page breaks are often difficult to program and the source of many bugs and memory problems. Using logos as vector graphics or embedding TrueType fonts is often required, but not possible with most libraries.

Sunday, December 2, 2012

The power of column stores

  • using column stores instead of row based stores can reduce access logs from 10 GB to 130 MB of disk space
  • reading compressed log files is 4 times faster than reading uncompressed files from hard disk
  • column stores can speed up analytical queries by a factor of 18-58

Tuesday, November 27, 2012

Runtime vs. memory usage

Oftentimes, better runtime can result in higher memory usage. Here is an example to create some strings to test bulk inserts on Redis:

Tuesday, November 20, 2012

Developers's time of permanency is 15 years?

This article is not about performance of PHP, but more about performance of developers in general.
A nice article from claims that the developers's time of permanency is - exactly - 15 years.

Tuesday, November 6, 2012

Applying Scrum to legacy code and maintenance tasks

There are some problems with Scrum that mainly occur when dealing with third party components or legacy systems:
  • wrong estimations (time, impact, risk, complexity)
  • bad requirements (inconsistent, incomplete, testable, conflicting, faulty)
  • development involved in operations (bug analysis, data correction, deployment, hot-fixes)
  • delays in development (bugs in legacy system, missing documentation)
  • testing (quality/quantity of test cases, un-mockable interfaces, long running offline processes, performance issues, live and test system differ)

Monday, October 29, 2012

How to implement a real-time chat server in PHP using Server-Sent Events (update: added C benchmark)

Lessons learned:
  • A web server written in PHP can give more than 10000 req/s on small hardware
  • A web server written in PHP is not slower than being written in Java (without threads)
  • A web server written in PHP is 30 percent slower than being written in C (without threads)
  • Realtime applications can be developed in PHP without problems

Friday, October 19, 2012

PHP Framework Comparison (update: opcode caching)

Reading about PHP frameworks, you'll get a lot about Symfony and Zend Framework. It is true that these frameworks have a lot of features and do great marketing. But what about performance and scalability?

Friday, September 14, 2012

Members, __set, __get, ArrayAccess and Iterator

Lessons learned:
  • __set() is 5 times slower than setting a member
  • __get() + __set() is 13 times slower than incrementing a member
  • Iterator is 4 times slower than using a member
  • ArrayAccess is 3 times slower than setting an element in a member array
  • ArrayAccess is 6 times slower than incrementing an element in a member array

Thursday, September 13, 2012

Mass inserts, updates: SQLite vs MySQL (update: delayed inserts)

Lessons learned:
  • SQLite performs inserts 8-14 times faster then InnoDB / MyISAM
  • SQLite performs updates 4-8 times faster then InnoDB and as fast as MyISAM
  • SQLite performs selects 2 times faster than InnoDB and 3 times slower than MyISAM
  • SQLite requires 2.6 times less disk space than InnoDB and 1.7 times more than MyISAM
  • Allowing null values or using synchronous=NORMAL makes inserts 5-10 percent faster in SQLite

Sunday, August 12, 2012

How to implement a real life benchmark with PHP

To determine the maximum capacity of a web page, Apache ab is often used in the first step. Fetching one URL very often is optimal for caching and gives a best case. To get the worst case for caching, it is necessary to fetch different URLs in a random order.

Monday, August 6, 2012

MySQLi prepared statements

Lessons learned:
  • Prepared statements are 13 percent faster than normal statements with escaping
  • Prepared statements are 8 percent faster than normal statements without escaping
  • To get improvements, you need at least 10000 inserts for 1 statement
  • Using insert...set is 0.5-1 percent faster than insert...values

Thursday, August 2, 2012

ircmaxell: Framework Fixation - An Anti Pattern

ircmaxell: Framework Fixation - An Anti Pattern, short summary:
  • delegation of architecture decisions to frameworks may not be optimal or even wrong
  • only use frameworks when doing prototypes or projects you don't need to maintain
  • frameworks don't save time/money in the long term
  • frameworks don't make it easier to hire good programmers
  • using a framework prevents developers from understanding backgrounds
  • not all framework developers are super heroes (look at the bug trackers ...)
  • favor libraries over frameworks

Sunday, July 22, 2012

Using V8 Javascript engine as a PHP extension (update: write PHP session)

"We Are Borg PHP. We Will Assimilate You. Resistance Is Futile!"
Just got to something described as: This extension embeds the V8 Javascript Engine into PHP.
It is called v8js and the documentation is already available on, examples and the sources are here. V8 is known to work well in browsers and webservers like node.js, but does it work inside PHP? YES!

Saturday, July 21, 2012

MySQL or MySQLi or PDO

Lessons learned:
  • MySQLi is 3-4 times slower than MySQL when fetching less then 500 datasets
  • MySQLi is 2-4 times faster than MySQL when fetching more than 500 datasets
  • PDO is 2-5 times slower than MySQL/MySQLi
  • Unbuffered queries are 15-40 percent faster than buffered queries in MySQLi
  • Unbuffered queries are 10-25 percent faster than buffered queries in MySQL for less than 10000 datasets
  • Unbuffered queries are 3-7 percent slower than buffered queries in MySQL for more than 10000 datasets
  • Unbuffered queries are 0-5 percent faster than buffered queries in PDO
  • Non thread safe versions of PHP on win32 are 50 percent faster than thread safe versions

Friday, July 20, 2012

ircmaxell: Is Autoloading A Good Solution?

ircmaxell: Is Autoloading A Good Solution?: at a 75% class usage tradeoff point, it doesn't really make sense not to autoload, especially given all of the other benefits. So in the end, it looks like autoloading is indeed a good solution...
From the comments: Simply enabling APC sped up the fixed requires by 82%, and the autoloading by an amazing 91%.

Wednesday, July 18, 2012

Decorator or Subclassing?

Using anonymous functions in PHP is very nice to implement a decorator, but what about performance? Results:
  • Subclassing is 40 percent faster than using a decorator
  • Subclassing might require a bit more code

Tuesday, July 17, 2012

How to write a really small and fast controller with PHP (update: benchmark Slim, Silex, Zend Framework, Symfony2)

To handle a lot of traffic, we need a fast controller with very little memory overhead. First, we implement a dynamic controller.

The design is based on the micro frameworks Slim and Silex. The first example maps the URL "http://server/index.php/blog/2012/03/02" to a function with the parameters $year, $month and $day:
// index.php, handle /blog/2012/03/02
$app = new App();
$app->get('/blog/:year/:month/:day', function($year, $month, $day) {
  printf('%d-%02d-%02d', $year, $month, $day);

Thursday, July 12, 2012

How to implement i18n without performance overhead

i18n is always difficult to implement and costs a lot performance. Normally, implementations use gettext() or a custom t()-function to translate a string. t() searches a INI or XML file for a translation key and returns the value. For example t('setting', 'de'), gives the German translation 'Einstellung'.

Typical optimizations use associative arrays (hashmaps) loaded into APC or Memcached. This requires a lot of memory for the array and produces a lot of cpu cycles for calling t() all the time. So the question is, can we do this better?

Yes! We use a just-in-time compiler for our PHP files and write the compiled PHP files to disk, so APC can cache them like regular PHP files.

Array key lookup: isset() or array_key_exists() or @ ?

Lessons learned:
  • isset() is faster than array_key_exists()
  • array_key_exists() is faster than @
  • @ is slower than ignoring notices with error_reporting()

Tuesday, July 10, 2012

PHP Deployment with Dropbox

Deploying files over sFTP or scp is boring and takes a lot of time. Using git with commit-hooks to initiate the deployment process is comfortable, but there is a solution that's even faster:

Deploy your server(s) with a Dropbox!

Here we go, first create a new Dropbox account:

Tuesday, July 3, 2012

Development Principles - Think first programming

A professor once told me:
Remember, a string goes into the server, a string goes out. Not more, not less.

So let's ask the following questions:
  • do you need a seven tier architecture?
  • do you need to write a servlet container in PHP?
  • do you need to derive a class more than twice?
  • where do you need OOP?
  • do you need design patterns?
  • how to choose the right technology?

Saturday, June 30, 2012

Disadvantages of ORM

ORM has attracted a lot of attention in the last years. So let's get a bit deeper into it.
The biggest advantage of ORM is also the biggest disadvantage: queries are generated automatically
  • queries can't be optimized
  • queries select more data than needed, things get slower, more latency
    (some ORMs fetch all datasets of all relations of an object even though only 1 attribute is read)
  • compiling queries from ORM code is slow (ORM compiler written in PHP)
  • SQL is more powerful than ORM query languages
  • database abstraction forbids vendor specific optimizations

Tuesday, June 26, 2012

Things you should not do in PHP (update: references)

Here is a list of things you should not do in PHP. Most of the stuff is pretty obvious, but over the years I've seen a lot of them. In most cases, these problems remain hidden until data grows above 10000 entries. So on a development system, things are always fast and there are no problems with memory limits :-)

Suppose we have a table with 100k entries:
$db->query('create table stats (c1 int(11) primary key, c2 varchar(255))');
for ($i=0; $i<100000; $i++) {
  $db->query('insert into stats values ('.$i.','.($i*2).')');
Populate a big array instead of streaming results:
$result = $db->query('select * from stats');
$array = $result->fetch_all(); // 35M
// or
while ($row = $result->fetch_assoc()) $array[] = $row; // 35M
// or
while ($row = $result->fetch_array()) $array[] = $row; // 44.5M
// process $array ...

// instead of:
while ($row = $result->fetch_assoc()) { // 0.5M
  // process $row

Wednesday, June 20, 2012

Replace Smarty with PHP templates

In many performance guides, Smarty is considered to be removed to speed up things. But oftentimes it's not Smarty causing performance problems, but rather big modifier chains not being cached. To point this out, we need to profile our template which is quite difficult when Smarty compiles in into something unreadable. So we need a quick and easy way to replace the Smarty template engine with pure PHP code. Since Smarty can't do more than PHP, let's replace Smarty with simple PHP templates.

So I'm providing here a small guide to replace Smarty with simple PHP based templates. These can be also cached by APC without any compiler.

First thing: Smarty configuration files
e.g. core.conf
foo = bar

logo = public/img/logo.png 
link = 
notice = Photo from xy 
bg_grey = #F5F5F5

Now let's convert it to PHP:
  $config = array(
    "logo" => "public/img/logo.png",
    "bg_grey" => "#F5F5F5" 
  $config["core"] = array( 
    "logo" => "public/img/logocore.png", 
    "link" => "", 
    "notice" => "Photo from xy"

Tuesday, June 19, 2012


Welcome to my first blog!

Yes, I'm a bit late in 2012, but I've collected some important things I'd like to write down and analyze in more detail.

In the daily IT business, it is often unclear if software should be optimized or better hardware should be ordered. This blog should help you to make this decision easier by looking at the benchmarks of possible software optimizations.

Here is a small agenda of the things I'll write in the next weeks:
  • The impact of APC/Optimizer+
  • APC vs Memcached (local vs distributed cache, refresh, serialization)
  • The power of cache warming
  • How to write a really small and fast AJAX controller with PHP
  • How to write a really small and fast O/R-mapper with PHP
  • How to write a really small and fast CMS
  • Why entity–attribute–value is bad for performance
  • How to benchmark a PHP framework
  • How to find the right PHP framework (or why to write your own)
  • How to implement client side session storage
  • Iteration vs Recursion
  • ...


performance (23) benchmark (6) MySQL (5) architecture (5) coding style (5) memory usage (5) HHVM (4) C++ (3) Java (3) Javascript (3) MVC (3) SQL (3) abstraction layer (3) framework (3) maintenance (3) Go (2) Golang (2) HTML5 (2) ORM (2) PDF (2) Slim (2) Symfony (2) Zend Framework (2) Zephir (2) firewall (2) log files (2) loops (2) quality (2) real-time (2) scrum (2) streaming (2) AOP (1) Apache (1) Arrays (1) C (1) DDoS (1) Deployment (1) DoS (1) Dropbox (1) HTML to PDF (1) HipHop (1) OCR (1) OOP (1) Objects (1) PDO (1) PHP extension (1) PhantomJS (1) SPL (1) SQLite (1) Server-Sent Events (1) Silex (1) Smarty (1) SplFixedArray (1) Unicode (1) V8 (1) analytics (1) annotations (1) apc (1) archiving (1) autoloading (1) awk (1) caching (1) code quality (1) column store (1) common mistakes (1) configuration (1) controller (1) decisions (1) design patterns (1) disk space (1) dynamic routing (1) file cache (1) garbage collector (1) good developer (1) html2pdf (1) internationalization (1) invoice (1) just-in-time compiler (1) kiss (1) knockd (1) legacy code (1) legacy systems (1) logtop (1) memcache (1) memcached (1) micro framework (1) ncat (1) node.js (1) openssh (1) pfff (1) php7 (1) phpng (1) procedure models (1) ramdisk (1) recursion (1) refactoring (1) references (1) regular expressions (1) search (1) security (1) sgrep (1) shm (1) sorting (1) spatch (1) ssh (1) strange behavior (1) swig (1) template engine (1) threads (1) translation (1) ubuntu (1) ufw (1) web server (1) whois (1)