LinkedIn Sourceforge

Vincent's Blog

Pleasure in the job puts perfection in the work (Aristote)

Fapws versus GO

Posted on 2019-02-10 21:17:00 from Vincent in OpenBSD fapws

I'm still looking for a replacement to the good old fapws web server. So, in this blog, I will put fapws in front of web server written in Go


The context of the comparison

As already post on this blog, I'm comparing Fapws to other web server who could be simple to use and have a small memory foot print.

This time, I'm comparing Fapws with a Web server written in Go.

Since the context of Go, I would expect much quicker results than Fapws. But, for the memory foot print, I'm interested to see which tool is the smallest.

The test methodology

I'm doing all test on the same machine. A Dell 5450 running OpenBSD 6.4.

The test will consist of ApacheBenchmark execution with different concurrent requests.

The Go program will be executed with the command: go run hello.go

For Fapws, we will do: python2.7 hello.py

The Fapws code

I'm using the hello.py script present in the sample folder of Fapws3.

Since the amazing results, I've also compared both solutions when presenting static files.

#!/usr/bin/env python

import fapws._evwsgi as evwsgi
import fapws
import fapws.base
import fapws.contrib
import fapws.contrib.views
import sys
sys.setcheckinterval(100000) # since we don't use threads, internal checks are no more required

import views

def start():
    evwsgi.start("0.0.0.0", "8085")

    evwsgi.set_base_module(fapws.base)

    def index(environ, start_response):
        print "GET:", environ['fapws.uri']
        return views.index(environ, start_response)

    def mystatic(environ, start_response):
        s=fapws.contrib.views.Staticfile("static/")
        return s(environ, start_response)

    evwsgi.wsgi_cb(("/static/",mystatic))
    evwsgi.wsgi_cb(("/", index))
    #evhttp.gen_http_cb(generic)
    evwsgi.set_debug(0)    
    print "libev ABI version:%i.%i" % evwsgi.libev_version()
    evwsgi.run()

if __name__=="__main__":
    start()

Go web server

For Go I'm using the following script which is a collection of samples I've found on internet

package main

import (
        "fmt"
        "log"
        "net/http"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello world!") // send data to client side
}

func staticFile(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "page") // send data to client side
}

func main() {
        fs := http.FileServer(http.Dir("static"))
        http.Handle("/static/", http.StripPrefix("/static/", fs))
        http.HandleFunc("/", sayhelloName)       // set router
        err := http.ListenAndServe(":9090", nil) // set listen port
        if err != nil {
                log.Fatal("ListenAndServe: ", err)
        }
}

Results

Hello world

The first test is to return the simple "Hello World".

In both cases, I've asked ApacheBenchmark to perform 100.000 requests.

For 100.000 requests, the results are:

concurrencyGoFapws
1028343582
50036063341
100023932643

The memory values are:

GoFapws
VSZ1137045880
RSS1150012588

Those results are un-expected. It means that Python with bunch of C code has the same performance of Go.

Let's see what will be the results with a small static file ans with a much bigger static file. This is a much representative test.

Small static file

The small file will be a file of 9,7kB. This is typically a css or an icon we can often see on web sites.

Still for 100.000 request, the results are:

concurrencyGoFapws
1022663587
50020233374
100022923012

The memory values are:

GoFapws
VSZ1126607480
RSS1670414184

Those results are still amazing. Fapws is in fact better for such use case.

Big static file

The file will be a file of 2.1MB. This is typically a picture file we can see on web sites.

Still for 100.000 request, the results are:

concurrencyGoFapws
1075132
50099108
1000na104

For a concurrency of 1000, Go stopped working by saying: "too many open files, retrying in 5 ms"

The memory values are:

GoFapws
VSZ1137047120
RSS1372413368

Those results are still amazing. Fapws is in fact better for such use case.

Conclusion

Surprisingly, Go is not better than Fapws. Moreover the memory foot print is quite bad.
But this last element could be improved. Indeed, after having spent some time this year at the Fosdem, I saw the following presentation. A novice like me in Go, will understand that memory could be drastically reduced, but need a certain expertise.

I think that the remaining test is to compare Fapws with Rust.



0, 1
displayed: 5364



What is the first letter of the word Moon?