DEV Community

Cover image for Simple web server in Perl and Go, Finally
suntong
suntong

Posted on

3 1

Simple web server in Perl and Go, Finally

OK, where were we and why we are here?

Quoting from my blog that started all these:

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 was Perl performs better than Go, two times that I tried & blogged: 1 & 2.

The Go community was not very happy about it, and neither do I, as a matter of fact, because I do believe that Go should be faster than Perl. Many people have given good & valid inputs as where things might get
improved, and I did try out everyone's suggestion to see how things can improve, including avoiding regular expressions, or using the high performance web framework echo (including echo v4), but all are just marginally faster, or have no obvious benefit at all, in which case I didn't even log a version.

That was quite some hectic journey, but long story short, I finally made it, with helps I got from various sources -- I finally made Go faster than Perl!!!

And here are the test results from my machine (which I published here):

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

GoPerl

From this we can see Go is on-par with Perl for the ballpack of the results. OK, then why I said Go is now faster than Perl?

Take a look at the Apache Bench's statistics first:

For Perl:

$ ab -n 500 -c 100 -g Perl100.txt http://192.168.0.10/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.0.10 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests


Server Software:        
Server Hostname:        192.168.0.10
Server Port:            80

Document Path:          /
Document Length:        43 bytes

Concurrency Level:      100
Time taken for tests:   0.112 seconds
Complete requests:      500
Failed requests:        0
Total transferred:      83500 bytes
HTML transferred:       21500 bytes
Requests per second:    4450.18 [#/sec] (mean)
Time per request:       22.471 [ms] (mean)
Time per request:       0.225 [ms] (mean, across all concurrent requests)
Transfer rate:          725.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.1      0       6
Processing:     1    6   0.9      6       8
Waiting:        1    6   0.9      6       8
Total:          6    7   0.8      6      11
WARNING: The median and mean for the total time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      7
  75%      7
  80%      7
  90%      7
  95%      8
  98%     10
  99%     10
 100%     11 (longest request)
view raw Perl.md hosted with ❤ by GitHub

For Go:

$ ab -n 500 -c 100 -g Gofh.txt http://192.168.0.11:8888/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.0.11 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests


Server Software:        fasthttp
Server Hostname:        192.168.0.11
Server Port:            8888

Document Path:          /
Document Length:        43 bytes

Concurrency Level:      100
Time taken for tests:   0.043 seconds
Complete requests:      500
Failed requests:        0
Total transferred:      117000 bytes
HTML transferred:       21500 bytes
Requests per second:    11675.42 [#/sec] (mean)
Time per request:       8.565 [ms] (mean)
Time per request:       0.086 [ms] (mean, across all concurrent requests)
Transfer rate:          2668.02 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   1.1      3       4
Processing:     1    5   3.8      4      21
Waiting:        1    5   3.8      4      21
Total:          1    8   3.9      7      22

Percentage of the requests served within a certain time (ms)
  50%      7
  66%      7
  75%      7
  80%      8
  90%     17
  95%     17
  98%     18
  99%     22
 100%     22 (longest request)
view raw FastHTTP.md hosted with ❤ by GitHub

I.e., for the Requests per second (#/sec), Perl is 4450.18 while Go is 11675.42. That's 2.6 times of Perl's throughput, while not sacrificing individual's response time much.

Moreover, when the load is light (< 70), which is the most common situation for my specific case, Go is faster than Perl.

So I'm quite happy with the result now.

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (3)

Collapse
 
ferdnyc profile image
Frank Dana

Hey, here's a question. (I just happened to wander past this again, no idea why. But something jumped out at me.)

In the Perl stats, we see:

Complete requests:      500
Failed requests:        0
Total transferred:      83500 bytes
HTML transferred:       21500 bytes

But the Go stats show:

Complete requests:      500
Failed requests:        0
Total transferred:      117000 bytes
HTML transferred:       21500 bytes

...Why is Go transferring so much more data? Especially for the same amount of HTML served?

Collapse
 
ferdnyc profile image
Frank Dana

So in the words of Obi-Wan, Go is faster "from a certain point of view." (And only if you don't mind that, in exchange for that marginally faster light-load performance, the Go version handles higher load much less smoothly than the Perl server.)

Don't get me wrong, I agree that for most applications, that's preferable.

Collapse
 
suntong profile image
suntong

Yep, agree, that's pretty accurate description of the situation, and conclusion as well.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more