Hi Symfonians,

Long time since my last post ! But it's mainly because I actually have a lot of work with Symfony 2 projects. One of my current task is to optimize the performances of a Symfony2.0.x project. I was curious to test the Twig C extension to check if there was a real improvement before using it in our production environment. Here we go:

I will not describe the installation as it is very easy, just follow the official documentation. When the extension is correctly installed you have a new Twig entry in your phpinfo():


The benchmark


To test the extension, I choose the most complex page of the site (complex at the Twig level):

  • Renders a tree of about 500 checkboxes
  • Recursive include calls are made inside the templates
  • Widget rendering does not use the Symfony2 form helpers


The main template:

<h3>Categories</h3>
<ul>
for rankLevel1, field in form.datas.Category.choices
include 'ThemesBundle:Search:_group_tree.html.twig' with {'form': form, 'widget': 'Category', 'rankLevel1': rankLevel1, 'level': 1, 'field': field }
endfor
</ul>
view raw gistfile1.twig hosted with ❤ by GitHub

(Called 6 times with different data)

The recursive Twig template _group_tree.html.twig:

PS: Note here that we didn't used here a native Symfony2 form, because the rendering (bind + renderering) was taking about 5 seconds...

Test conditions:

  • Symfony 2.0.22, of course the production environment is used for the test.
  • PHP 5.3.2-1ubuntu4.18 with Suhosin-Patch (cli) (built: Sep 12 2012 19:12:47)
  • php app/check.php, no warning or error, APC is enabled with an APC autoloader.


Results without the extension:

  • 1000 iterations
  • Apache was restarted and Symfony2 cache was cleared between each test

The following results are the second run because the 1st run has to rebuild the Symfony cache.

[10:39:54] coil@ubuntu:~/Webdev$ ab -n 1000 http://dev.project.com/search
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking dev.project.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.14
Server Hostname:        dev.project.com
Server Port:            80

Document Path:          /search
Document Length:        197192 bytes

Concurrency Level:      1
Time taken for tests:   99.232 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      197742000 bytes
HTML transferred:       197192000 bytes
Requests per second:    10.08 [#/sec] (mean)
Time per request:       99.232 [ms] (mean)
Time per request:       99.232 [ms] (mean, across all concurrent requests)
Transfer rate:          1946.03 [Kbytes/sec] received

Connection Times (ms)
	      min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    95   99   4.4     98     190
Waiting:       92   96   4.2     95     187
Total:         95   99   4.4     98     190

Percentage of the requests served within a certain time (ms)
  50%     98
  66%    101
  75%    102
  80%    102
  90%    103
  95%    104
  98%    108
  99%    110
 100%    190 (longest request)


Results with the extension enabled:


[10:36:34] coil@ubuntu:~/Webdev$ ab -n 1000 http://dev.project.com/search
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking dev.project.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.14
Server Hostname:        dev.project.com
Server Port:            80

Document Path:          /search
Document Length:        197192 bytes

Concurrency Level:      1
Time taken for tests:   84.887 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      197742000 bytes
HTML transferred:       197192000 bytes
Requests per second:    11.78 [#/sec] (mean)
Time per request:       84.887 [ms] (mean)
Time per request:       84.887 [ms] (mean, across all concurrent requests)
Transfer rate:          2274.87 [Kbytes/sec] received

Connection Times (ms)
	      min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    81   85   2.9     84     127
Waiting:       78   82   2.7     81     124
Total:         81   85   2.9     84     127

Percentage of the requests served within a certain time (ms)
  50%     84
  66%     86
  75%     87
  80%     87
  90%     88
  95%     89
  98%     91
  99%     94
 100%    127 (longest request)


(I have run the tests several times to check that the results are reliable)

Conclusion


As you can see, it is quiete interesting as the global gain is about 14,5%. I have tested on several smaller templates but the gain was insignificant and less than 1%. (which seems logical)

So the extension can really be helpful on complex templates with a lot of parameters, the more complex the Twig templates are the more gain you will have. (up to 15%)

See you. COil :)


About the extension:


For other Symfony 2 performance tricks check out the following resources: