Simple web server implemented in Perl and Go
Tags: webdev, go, perl, performance
Published: 2019-06-07 02:23:52

---
title: Simple web server implemented in Perl and Go
published: true
description: website performance based on implementation of Perl or Go
cover_image: https://i.stack.imgur.com/zBz23.png
tags: webdev,go,perl,performance
---

Back in my mind, I had always thought that Perl is slow, comparing to compiled languages, like C/C++. So it is always in my mind that I should rewrite my simple web server from Perl to a compiled language. Finally I did, and the result is astonishing to me.

<!--more-->

- This is [my simple web server in Perl](https://github.com/suntong/dbab/blob/master/src/bin/dbab-svr)
- And this is [my rewrite done in Go](https://github.com/suntong/dbab-go/blob/c082f2ddc515e652c76c5897ccce4ae431b864c5/dbab-svr/main.go)

Both are pretty simple. 

How they stack up against each other? 

I had believed that the Go implementation should be much faster than the Perl code, since it is a compiled language, and also that the Go http server is said to be a production grade software that lays a solid foundation for Go web applications. However I'm astonished to find out that the result is just the opposite. 

Here is a light load situation, of 100 concurrency requests (the number of multiple requests to perform at a time):

![Ab100](https://img.vim-cn.com/15/6463e0025d73a265070b76935b030887c58087.svg "100 concurrency requests")

We can see that it is no-sweat for Perl, however for Go, the response time has jumped to about 5 times than the initial value (when there was almost zero load) in the end. 

Here is a load situation that finally pushed the response time up for Perl:

![Ab500](https://img.vim-cn.com/c6/635682fa3a90f909fa2dd4c8ec6cfb57e13388.svg "500 concurrency requests")

This time, the concurrency requests is 500. We can see that for Perl, the situation get deteriorated at the very end. However for Go, it starts twice or four times as slow as the previous case when there was almost zero load (from 5ms to 20ms), and it keeps deteriorating, until it is close to 70ms, then jumped rapidly upwards. 

So the lesson I learned today is, Perl is not only a fast prototyping language, when it comes to simple web servers like this, Perl performs much better than Go too. 

PS. 

The two load situations are generated by Apache Bench, 
using `ab -n 500 -c 100` and `ab -n 1500 -c 500` respectively. I've published the raw test results [here](https://gist.github.com/suntong/b259a3730e40c017e6a1020339bd356c), and  there statistic summaries are included at the end of the article.

PPS. 

Shameless plugin - [my simple web server in Perl](https://github.com/suntong/dbab/blob/master/src/bin/dbab-svr) is the core of my [dbab package](https://github.com/suntong/dbab), the dnsmasq based ad blocking, which is ad-blocking done at the DNS level -- all requests to ad-sites are blocked right there at DNS. No more user space extensive pattern matching & replacing necessary any more. It is feather weight, both in terms of package size and CPU usage. It can speed up mobile device browsing without installing any apps to them. I'm working to release a new version soon...

Now the raw test results.

Perl:

```
Concurrency Level:      500
Time taken for tests:   0.333 seconds
Complete requests:      1500
Failed requests:        0
Total transferred:      222000 bytes
HTML transferred:       64500 bytes
Requests per second:    4509.60 [#/sec] (mean)
Time per request:       110.875 [ms] (mean)
Time per request:       0.222 [ms] (mean, across all concurrent requests)
Transfer rate:          651.78 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.9      0      21
Processing:     1    6   0.7      6       8
Waiting:        1    6   0.7      6       8
Total:          5    7   2.4      6      25

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      6
  75%      7
  80%      7
  90%      7
  95%      7
  98%     22
  99%     23
 100%     25 (longest request)
```

Go:

```
Concurrency Level:      500
Time taken for tests:   0.250 seconds
Complete requests:      1500
Failed requests:        0
Total transferred:      324000 bytes
HTML transferred:       64500 bytes
Requests per second:    6007.50 [#/sec] (mean)
Time per request:       83.229 [ms] (mean)
Time per request:       0.166 [ms] (mean, across all concurrent requests)
Transfer rate:          1267.21 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   17   7.5     16      34
Processing:     6   33  16.1     31      90
Waiting:        5   28  14.9     27      87
Total:          7   49  16.3     48     111

Percentage of the requests served within a certain time (ms)
  50%     48
  66%     52
  75%     62
  80%     63
  90%     68
  95%     80
  98%     96
  99%    101
 100%    111 (longest request)
```