Simple web server in Perl and Go, Revisit
Tags: webdev, go, html, performance
Published: 2019-06-08 03:01:51

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

Following on my previous [Simple web server implemented in Perl and Go](https://dev.to/suntong/simple-web-server-implemented-in-perl-and-go-b43/) 
 blog, which has been pointed out as unfair comparison. This time, thanks to [Axel Wagner](https://dev.to/themerovius), who replaced the net/http.Server layer with direct translation of Perl code, the code is now reading and writing directly to a socket, just as what the Perl code is doing. 


And here are the test results from my machine again (which I [published here](https://gist.github.com/suntong/757d287f4fe44a543b15fa73d6f30abb)):

100 concurrency requests (the number of multiple requests to perform at a time):

![Ab100](https://img.vim-cn.com/93/4bdabb7ad9b7e8bb68176c759d640c1e747b6f.svg "100 concurrency requests")

500 concurrency requests:

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


Once again,

- This is [the implementation in Perl, with Cache-Control Header added, to be fair](https://github.com/suntong/dbab/blob/master/src/bin/dbab-svr)
- And this is [the implementation in Go](https://github.com/suntong/dbab-go-log/blob/232d5fe68e7c16c92da5a1eb8eb4d4c79b7daaf7/dbab-svr/main.go)
- As discussed previously, statistic summaries of Apache Bench are a bit confusing so I'm leaving them out this time. Also concluded was that the measured & reported response time are truly trustworthy. 

From the charts, we can see that the response time for Go 500 concurrency requests is almost identical to [previous result](https://dev.to/suntong/simple-web-server-implemented-in-perl-and-go-b43/), while the 100 concurrency is actually worth than before.

In summary, I'm still seeing Perl performs much better than Go, with this direct translation. Why? Could starting the Go server as myself instead of root be the culprit, or something else? 

**UPDATE:** 

What I was expecting to see? Quoting from a comment from previous blog:

> ... That perl still ends up with significantly higher average response times is… honestly, a confirmation that it's not a very fast language.
>
> BTW, I also used a different tool to benchmark (github.com/rakyll/hey). AIUI, it uses multiple cores more efficiently. With that tool, the perl implementation gets absolutely demolished, with an average response time ~40x higher than the Go implementation on my machine.


Having `ab` failed for me to produce the anticipated result, I installed the suggested [hey](https://github.com/rakyll/hey), and test results indeed show that Go is better than Perl. 


**Further UPDATE:** 

I tested with [hey](https://github.com/rakyll/hey)'s default settings. 

For Perl:

`hey -disable-keepalive http://192.168.0.10/`

![Perl](https://img.vim-cn.com/ce/f1df6bc22c5b5d5b9f6b377d5f3e68a8c4df58.png "Perl")


For Go:

`hey -disable-keepalive http://192.168.0.11:8888/`


![Go](https://img.vim-cn.com/cf/5c0aca6cbbdeb90a9cb08849e2df63efd89c0f.png "Go")

(Note that both `192.168.0.10` and `192.168.0.11` are my local machine, as I have [configured two IP address](https://github.com/suntong/blog/blob/master/DbabAll.md) for it.)


And the conclusion that _"the test results indeed show that Go is better than Perl"_ was draw upon the `Response time histogram`. However, when I thought more into it, it doesn't make sense to me any more. 

The [hey](https://github.com/rakyll/hey)'s default settings are:

```
Usage: hey [options...] <url>

Options:
  -n  Number of requests to run. Default is 200.
  -c  Number of requests to run concurrently. Total number of requests cannot
      be smaller than the concurrency level. Default is 50.
```

As we can see in the [previous result](https://dev.to/suntong/simple-web-server-implemented-in-perl-and-go-b43/), the Perl server survives the 500 concurrent requests gracefully, with 95% percentile reading of only 7ms. However hey is telling a different story that, with only 200 concurrent requests, the Perl server's response time is mostly 0.105 _seconds_. However, 

That is _15 times_ than `ab`'s reading. 

Hey's inability of getting accurate reading at `ms` level makes me doubt it's own accuracy, and I have to suspect that hey's 15-time response time reading is due to _its own_ slack. 

Moreover, if you take a closer look at hey's Latency distribution readings, we can see that Perl at 75% is still 0.0181secs, while Go, at 75% is already 0.0222secs. Let alone at 10%, Perl is 0.0045secs while Go is 0.0150secs (>3 times more). For this we can see that hey's reading is contradicting with themselves and Perl clearly performs much better than Go from hey's Latency distribution readings.

Furthermore, that 13 long 1.043sec response time from the Perl server is only observed in hey, all the other performance testing software, including the not-documented-here [httperf](https://github.com/httperf/httperf), none of them have exhibited such behavior. So it is fair to conclude that the long 1.043sec response time is caused by hey _itself_, not by the Perl server. 

So, up to now, for all above three reasons, I have to conclude that hey is not suitable for this test due to its own limitations, thus cannot stacks up against the most popular Apache Bench.

Now, it is getting more and more interesting -- _who and what to trust_. Yeah, that _deserves another blog_, which I will turn into _commercial_ web performance testing software, which I happen to have access to. It's not as simple as one command, but needs lots of steps just to set it up. But, I'll do it, to see how it looks like from the commercial tool (by Microsoft) that has been used and depended on by millions of companies. 

Stay tuned...