Blog about software development


Porting PHP-CRUD-API to Go

17 Dec 2016 - by 'Maurits van der Schee'

I have ported the core of PHP-CRUD-API to Go and achieved a nice performance improvement from 6500 requests per second to 12000 requests per second. I found that PHP 7 outperforms C# with Kestrel on the .net Core platform for similar functionlity, whereas PHP 5 was still slower than C#. In PHP 7 the full program executes at roughly 2500 requests per second, which means the added logic makes you lose about two thirds of the performance. In compiled languages (like C# and Go) I expect that adding logic has a lower performance impact.

Hello world web service in Go

This is the code I found online for a fast Go-based "hello world" web server:

package main

import (

func hello(w http.ResponseWriter, r *http.Request) {
    w.Header().Add("Content-Type", "text/html;charset=utf8")
    io.WriteString(w, "<h1>Hello world!</h1>")

func main() {
    http.HandleFunc("/", hello)
    http.ListenAndServe(":8000", nil)

Install and run on a Debian based Linux using:

sudo apt-get install golang
go build hello

This is very fast (27k req/sec), which is about as fast as a helloworld.php file performs (with mod_php on Apache).

Porting the core of PHP-CRUD-API

Currently there are multiple implementations of the same (limited/core) functionality:

  1. Java, 14000 req/sec (source code)
  2. Go, 12000 req/sec (source code)
  3. PHP 7, 6500 req/sec (source code)
  4. C# (.net Core), 5000 req/sec (source code)
  5. Node.js, 4200 req/sec (source code)
  6. Python, 2600 req/sec (source code)

The tests are done using Apache Bench (ab -n 100000 -c 10) on my i7 Intel NUC.

The request is:

GET http://localhost:8000/posts/1

The output is:

{"category_id":"1","content":"blog started","id":"1","user_id":"1"}

As you can see a database round-trip is made (locally) and the data is formatted as JSON.

Proper benchmarking

While micro-benchmarks may give you an idea of the maximum performance achievable on a platform it does not mean much that the performance of Go's hello world is not better than that of PHP's implementation. Only when you start adding code to the web service then things change and difference in performance is becoming visible.

When you add code you see that Go is faster than PHP. I expect C# to be faster than PHP as well when the full application is ported. In the past C# was faster than PHP, because of PHP 5. PHP 7 performs a lot better than PHP 5 and therefor we now see that with the current limited amount of code PHP 7 is still faster than C# and Node.js.

Making proper benchmarks is hard. When you are creating micro-services with a database back-end then this benchmark may be relevant. This benchmark requires precise implementation of the same program in multiple languages, which is not easy, so I may have made mistakes. If you want me to optimize some code, then feel free to open an issue on Github!

Another project that is aimed at proper benchmarking is Techempower Framework Benchmark. It tries really hard to ensure it is comparing apples with apples. It compares multiple types of requests and also because the test code is on Github you can file an issue if a test can be improved.

PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.