May 30, 2012

Performance of CGI vs PHP

By Chris Heiland

This was originally posted on Chris Heiland’s staff blog while he was a member of the Web Team. Chris migrated this post to the Web Team blog before he left because we thought the content still had value to the UW community.


For the impatient folks who don’t want the history lesson, skip down to the Test Results.

A long time ago there was Common Gateway Interface (CGI), people used it because there was nothing better available. If you wanted your programming language on the web to generate HTML, there was no other option. The benefit was you could really use any language your server could support which ranged from popular such as perl, to the outright wacky bash.

To get started was easy, just declare the content type and then two carriage returns and you would have output. The simplest program was:

#!/bin/sh

echo 'Content-type: text/plain'
echo ''

echo 'Hello World'

Now you could get “Content-type: text/html” and put out more, but there’s plenty of material out there to read. However, this is not a history lesson, this is about performance. For a long time I insisted on using CGI when I wanted something fast. I’ve since moved from perl to python but the principle was the same.

As the UA servers (depts included) were recently upgraded I thought it was time to test this fast theory again. My assumption was PHP would be much slower and a poor choice if there was a need for speed. Using the popular ab I created two scripts to do the same thing.

The intent is to grab a json feed from an external source for the jquery script to do something with. Currently it’s acting as a proxy as a workaround the cross-site scripting limitations. In the future it will provide more advance server-side functionality that we wouldn’t want to deal with on the client.

Here are the links to the gists as the actual code would get too long to display.

Now we get to the important part, performance. In various order execution, we are looking for which script is faster. Maintainability is important as well but as the server sides are minimal I’ll take a substantial increase in speed.

Test Results

Test hardware: Lion running on a MacBook Pro 2.4GHz i5, 4GB Ram, SSD

Test command: ab -n 100 -c 10 http://example.com

Test 1 (cgi then php)

CGI:

Time taken for tests: 1.551 seconds
Total transferred: 43712 bytes
HTML transferred: 16200 bytes
Requests per second: 64.46 [#/sec] (mean)
Time per request: 155.124 [ms] (mean)
Time per request: 15.512 [ms] (mean, across all concurrent requests)
Transfer rate: 27.52 [Kbytes/sec] received

PHP:

Time taken for tests: 2.154 seconds
Total transferred: 43628 bytes
HTML transferred: 16200 bytes
Requests per second: 46.42 [#/sec] (mean)
Time per request: 215.438 [ms] (mean)
Time per request: 21.544 [ms] (mean, across all concurrent requests)
Transfer rate: 19.78 [Kbytes/sec] received

Test 2 (php then cgi)

PHP:

Time taken for tests: 1.540 seconds
Total transferred: 43712 bytes
HTML transferred: 16200 bytes
Requests per second: 64.95 [#/sec] (mean)
Time per request: 153.975 [ms] (mean)
Time per request: 15.397 [ms] (mean, across all concurrent requests)
Transfer rate: 27.72 [Kbytes/sec] received

CGI:

Time taken for tests: 1.528 seconds
Total transferred: 44281 bytes
HTML transferred: 16362 bytes
Requests per second: 65.47 [#/sec] (mean)
Time per request: 152.753 [ms] (mean)
Time per request: 15.275 [ms] (mean, across all concurrent requests)
Transfer rate: 28.31 [Kbytes/sec] received

Test 3 (cgi then php)

CGI:

Time taken for tests:   1.373 seconds
Total transferred:      43775 bytes
HTML transferred:       16200 bytes
Requests per second:    72.83 [#/sec] (mean)
Time per request:       137.300 [ms] (mean)
Time per request:       13.730 [ms] (mean, across all concurrent requests)
Transfer rate:          31.14 [Kbytes/sec] received

PHP:

Time taken for tests:   1.993 seconds
Total transferred:      43649 bytes
HTML transferred:       16200 bytes
Requests per second:    50.17 [#/sec] (mean)
Time per request:       199.333 [ms] (mean)
Time per request:       19.933 [ms] (mean, across all concurrent requests)
Transfer rate:          21.38 [Kbytes/sec] received

Test 4 (php then cgi)

PHP:

Time taken for tests:   1.303 seconds
Total transferred:      43754 bytes
HTML transferred:       16200 bytes
Requests per second:    76.77 [#/sec] (mean)
Time per request:       130.257 [ms] (mean)
Time per request:       13.026 [ms] (mean, across all concurrent requests)
Transfer rate:          32.80 [Kbytes/sec] received

CGI:

Time taken for tests:   1.474 seconds
Total transferred:      43670 bytes
HTML transferred:       16200 bytes
Requests per second:    67.83 [#/sec] (mean)
Time per request:       147.423 [ms] (mean)
Time per request:       14.742 [ms] (mean, across all concurrent requests)
Transfer rate:          28.93 [Kbytes/sec] received

Results Conclusion

What we find is a lack of variation between all the scripts. For the most part it looks like cgi might be slightly faster but it’s not at all consistent. The takeaway as far as I can see it is the choice doesn’t really matter, it’s all about what makes sense for the developing the app and maintenance.

Comments are closed.