I optimized a new hello world project based on symfony 1.0.6 to a level playing field that represents a complete dynamic dispatch cycle. I have disabled facilities for i18n, caching, databases, user security (though I have enabled sessions support), views with helpers. Basically removing all of the reasons you would want to use a framework, to produce a hello world page, yet represent a complete dynamic dispatch cycle.
Most of these facilities are enabled by default and this decreases the base time for a hello world style benchmark. For most web applications these defaults simplify the process of choosing a framework. Unlike other php frameworks, there is no need to glue together the usual pieces you will need for a decent web app. Yet, these features can easily be disable via a few configs if you want to test a hello world page!
Attached is the project I used and the benchmarks. Big improvements from symfony default based on a few quick tests. If there is anything I turned off that you feel is unfair, please let me know. I have tried to be as unbiased (fair and accurate) as possible in producing just a hello world page without all the framework extras.
There are two hello world tests, one with full view rendering (view configuration: meta, stylesheets, js, layout partial/component processing, loading of helpers, complete template rendering, etc) and one that just renders text, like hello world. Attached are some quick results for both.
urls:
/ -> /helloworld/faster
/helloworld/faster /helloworld/slower
That apache config I used is a slightly optimized config for apache2 on my mac; you can disregard. Also, fyi: apache2/php 5.2.3 with apc (and xdebug) enabled.
How to make an ideal symfony hello world test:
mkdir helloworld cd helloworld/ mkdir -p lib/vendor cd lib/vendor svn export http://svn.symfony-project.com/branches/1.0 symfony cd ../../ php lib/vendor/symfony/data/bin/symfony init-project helloworld ./symfony init-app helloworld ./symfony init-module helloworld helloworld ./symfony cc
if you move project from original starting point, edit config.php to make paths to symfony adaptable:
// symfony directories $sf_symfony_root_dir = dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'symfony'; $sf_symfony_lib_dir = $sf_symfony_root_dir.DIRECTORY_SEPARATOR.'lib'; $sf_symfony_data_dir = $sf_symfony_root_dir.DIRECTORY_SEPARATOR.'data';
[setup apache, link apache config to config/apache.conf, restart]
see: http://www.symfony-project.com/book/1_0/03-Running-Symfony
I used the following:
AddDefaultCharset utf-8
MaxRequestsPerChild 3600
<VirtualHost *>
ServerName sfperformance.com
DocumentRoot "/opt/local/apache2/htdocs/sfperformance/web"
DirectoryIndex index.php
LogLevel notice
ErrorLog /opt/local/apache2/htdocs/sfperformance/log/error.log
CustomLog /opt/local/apache2/htdocs/sfperformance/log/access.log combined
Options +FollowSymLinks +ExecCGI
FileETag None
DeflateFilterNote ratio
AddOutputFilterByType DEFLATE text/plain text/html application/xhtml+xml text/xml application/xml application/x-javascript text/javascript text/css
<Location />
Header append Vary User-Agent env=!dont-vary
</Location>
# symfony framework assets
Alias /sf /opt/local/apache2/htdocs/sfperformance/lib/vendor/symfony/data/web/sf
<Directory "/opt/local/apache2/htdocs/sfperformance/web">
AllowOverride None
Order allow,deny
Allow from All
php_admin_value realpath_cache_size 1024K
php_admin_value realpath_cache_ttl 3600
php_admin_value memory_limit 32M
php_admin_value post_max_size 32M
php_admin_value file_uploads 1
php_admin_value upload_max_filesize 32M
ExpiresActive On
ExpiresDefault A86400
ExpiresByType text/javascript A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType text/css A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType image/gif A604800
ExpiresByType image/png A604800
ExpiresByType image/jpeg A604800
ExpiresByType text/plain A604800
ExpiresByType application/x-shockwave-flash A604800
ExpiresByType video/x-flv A604800
ExpiresByType application/pdf A604800
ExpiresByType text/html A900
RewriteEngine On
RewriteCond %{REQUEST_URI} \..+$
RewriteRule .* - [L]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
# big crash from our front web controller
ErrorDocument 500 "<h2>Application error</h2>symfony application failed to start properly"
</Directory>
</VirtualHost>
Edit helloworld/apps/helloworld/config/settings.yml:
change the following settings for prod environment:
> all: > .actions: > default_module: helloworld # Default module and action to be called when > default_action: index # A routing rule doesn't set it > # Optional features. Deactivating unused features boosts performance a bit. > use_database: off # Enable database manager. Set to off if you don't use a database. > use_security: off # Enable security features (login and credentials). Set to off for public applications. > use_flash: off # Enable flash parameter feature. Set to off if you never use the set_flash() method in actions. > i18n: off # Enable interface translation. Set to off if your application should not be translated. > check_symfony_version: off # Enable check of symfony version for every request. Set to on to have symfony clear the cache automatically when the framework is upgraded. Set to off if you always clear the cache after an upgrade. > use_process_cache: on # Enable symfony optimizations based on PHP accelerators. Set to off for tests or when you have enabled a PHP accelerator in your server but don't want symfony to use it internally. > compressed: off # Enable PHP response compression. Set to on to compress the outgoing HTML via the PHP handler. > check_lock: off # Enable the application lock system triggered by the clear-cache and disable tasks. Set to on to > escaping_strategy: off # Determines how variables are made available to templates. Accepted values: bc, both, on, off. > no_script_name: on # Enable the front controller name in generated URLs > cache: off # Enable the template cache > etag: off # Enable etag handling > web_debug: off # Enable the web debug toolbar > # Helpers included in all templates by default > standard_helpers: [] > > # ORM > orm: off
for added boost since we only want to test a complete dynamic dispatch cycle:
edit helloworld/apps/helloworld/config/filters.yml, to disable cache, security, debug, flashes, and the addition of common view elements via filters:
> rendering: ~ > execution: ~ > > web_debug: > enabled: off > > security: > enabled: off > > cache: > enabled: off > > common: > enabled: off > > flash: > enabled: off
edit helloworld/apps/helloworld/config/factories.yml, uncomment defaults and disable symfony sessions from auto starting:
> all: > user: > class: myUser > > storage: > class: sfSessionStorage > param: > auto_start: off
edit helloworld/apps/helloworld/lib/myUser.class.php and change:
< class myUser extends sfBasicSecurityUser --- > class myUser extends sfUser
This will disable basic user authentication and credential management.
Since we have disabled output escaping we need to modify the default template:
helloworld/apps/helloworld/templates/layout.php
< <?php echo $sf_data->getRaw('sf_content') ?>
---
> <?php echo $sf_content; ?>
add hello world actions for testing:
edit helloworld/apps/helloworld/modules/helloworld/actions.class.php, add:
class helloworldActions extends sfActions
{
/**
* Executes index action
*
*/
public function executeIndex()
{
return $this->executeFaster();
}
public function executeFaster()
{
return $this->renderText('hello world');
}
public function executeSlower()
{
return sfView::SUCCESS;
}
}
add a template for full view comparison:
edit helloworld/apps/helloworld/modules/helloworld/templates/slowerSuccess.php, add:
hello world!
Add some routes for our actions:
edit helloworld/apps/helloworld/config/routing.yml
>
4c12
< param: { module: default, action: index }
---
> param: { module: helloworld, action: index }
Clear cache:
./symfony cc
Now we have disabled all of the optional components of symfony so that it is only loading and using core libraries, not any extras. If you do this on a mac book pro with apache2 / php5.2.3 / apc / xdebug, for the fast hello world action you can get at least 200qps. even faster without xdebug active.
Results my tests:
$ ab -c 50 -t 90 http://sfperformance.com/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Finished 20252 requests
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /
Document Length: 11 bytes
Concurrency Level: 50
Time taken for tests: 90.127642 seconds
Complete requests: 20252
Failed requests: 0
Write errors: 0
Total transferred: 8198372 bytes
HTML transferred: 223223 bytes
Requests per second: 224.70 [#/sec] (mean)
Time per request: 222.515 [ms] (mean)
Time per request: 4.450 [ms] (mean, across all concurrent requests)
Transfer rate: 88.83 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 41 42.2 30 196
Processing: 8 178 129.6 153 1413
Waiting: 0 158 129.2 126 1277
Total: 8 220 131.1 190 1413
Percentage of the requests served within a certain time (ms)
50% 190
66% 237
75% 276
80% 310
90% 399
95% 478
98% 577
99% 651
100% 1413 (longest request)
$ ab -c 15 -t 10 http://sfperformance.com/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient)
Finished 2309 requests
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /
Document Length: 11 bytes
Concurrency Level: 15
Time taken for tests: 10.6774 seconds
Complete requests: 2309
Failed requests: 0
Write errors: 0
Total transferred: 934452 bytes
HTML transferred: 25443 bytes
Requests per second: '''230.74''' [#/sec] (mean)
Time per request: 65.007 [ms] (mean)
Time per request: 4.334 [ms] (mean, across all concurrent requests)
Transfer rate: 91.14 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 4.1 0 33
Processing: 7 60 135.5 16 882
Waiting: 0 56 131.9 14 880
Total: 7 62 135.5 17 882
Percentage of the requests served within a certain time (ms)
50% 17
66% 24
75% 31
80% 34
90% 204
95% 417
98% 544
99% 638
100% 882 (longest request)
$ ab http://sfperformance.com/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient).....done
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /
Document Length: 11 bytes
Concurrency Level: 1
Time taken for tests: 0.9093 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Total transferred: 404 bytes
HTML transferred: 11 bytes
Requests per second: 109.97 [#/sec] (mean)
Time per request: '''9.093''' [ms] (mean)
Time per request: 9.093 [ms] (mean, across all concurrent requests)
Transfer rate: 0.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 8 8 0.0 8 8
Waiting: 8 8 0.0 8 8
Total: 8 8 0.0 8 8
$ ab -c 50 -t 90 http://sfperformance.com/helloworld/slower
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient)
Completed 5000 requests
Completed 10000 requests
Finished 12856 requests
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /helloworld/slower
Document Length: 591 bytes
Concurrency Level: 50
Time taken for tests: 90.57437 seconds
Complete requests: 12856
Failed requests: 0
Write errors: 0
Total transferred: 12663160 bytes
HTML transferred: 7597896 bytes
Requests per second: 142.75 [#/sec] (mean)
Time per request: 350.254 [ms] (mean)
Time per request: 7.005 [ms] (mean, across all concurrent requests)
Transfer rate: 137.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 20 29.5 4 194
Processing: 12 327 226.1 330 1543
Waiting: 0 317 227.2 320 1540
Total: 12 348 228.8 345 1543
Percentage of the requests served within a certain time (ms)
50% 345
66% 462
75% 513
80% 549
90% 650
95% 743
98% 846
99% 920
100% 1543 (longest request)
$ ab -c 15 -t 10 http://sfperformance.com/helloworld/slower
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient)
Finished 1328 requests
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /helloworld/slower
Document Length: 591 bytes
Concurrency Level: 15
Time taken for tests: 10.6420 seconds
Complete requests: 1328
Failed requests: 0
Write errors: 0
Total transferred: 1309065 bytes
HTML transferred: 785439 bytes
Requests per second: 132.71 [#/sec] (mean)
Time per request: 113.024 [ms] (mean)
Time per request: 7.535 [ms] (mean, across all concurrent requests)
Transfer rate: 127.72 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 9
Processing: 11 110 128.3 42 628
Waiting: 4 109 127.8 41 628
Total: 11 110 128.3 42 628
Percentage of the requests served within a certain time (ms)
50% 42
66% 122
75% 185
80% 221
90% 314
95% 380
98% 444
99% 508
100% 628 (longest request)
$ ab http://sfperformance.com/helloworld/slower
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking sfperformance.com (be patient).....done
Server Software: Apache/2.2.4
Server Hostname: sfperformance.com
Server Port: 80
Document Path: /helloworld/slower
Document Length: 591 bytes
Concurrency Level: 1
Time taken for tests: 0.16370 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Total transferred: 985 bytes
HTML transferred: 591 bytes
Requests per second: 61.09 [#/sec] (mean)
Time per request: 16.370 [ms] (mean)
Time per request: 16.370 [ms] (mean, across all concurrent requests)
Transfer rate: 0.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 16 16 0.0 16 16
Waiting: 15 15 0.0 15 15
Total: 16 16 0.0 16 16
Then again the whole idea of doing this is moot, because you don't use a framework for hello world. You use frameworks to build web apps and at its core symfony is extremely fast, obviously when you add i18n support, caching support, and a bunch of other useful stuff it slowly gets slower.

