Measuring the Lightweightness of Go by Looking at a Simple Web Service

Inspired by my article The lightweightness of microservices – Comparing Spring Boot, WildFly Swarm, and Haskell Snap, a colleague of mine implemented the same Web service using the Go programming language. You can find his code here: Bitbucket-repo. To compare his implementations with the other ones, I integrated it into the main project (GitHub-repo) and measured it. Here are the results. 🙂

Weight of the Implementation Effort

The implementation in Go is conceptually very similar to the Haskell Snap implementation, but syntactically very different:

func handler(w http.ResponseWriter, r *http.Request) {
	summand1, err1 := strconv.ParseFloat(r.URL.Query().Get("summand1"), 64)

	if err1 != nil {
		w.WriteHeader(http.StatusBadRequest)
		io.WriteString(w, "summand1 not a float")
		return
	}
	summand2, err2 := strconv.ParseFloat(r.URL.Query().Get("summand2"), 64)

	if err2 != nil {
		w.WriteHeader(http.StatusBadRequest)
		io.WriteString(w, "summand2 not a float")
		return
	}
	sum := summand1 + summand2
	io.WriteString(w, strconv.FormatFloat(sum, 'f', -1, 64))
}

The code is equally expressive as the Snap equivalent, but due to the well designed library functions the code is even shorter.

This diagram compares the size of the different implementations by counting the lines of code of all source files including the build scripts.
locs.png
With only 35 LOC the Go implementation is the shortest one, surprisingly followed by the Java EE standard implementation based on Wildfly. This is because the implementation uses all available conventions including the standard Maven support. The Haskell Snap implementation is the next in size, followed by Spring Boot and finally Wildfly Swarm.

Weights of Bits and Bytes

To judge the weight of the generated artifacts, there are (at least) two interesting things to measure: the size of the generated service and the size of the complete docker image. This diagram shows these two metrics for all implementations:

bitsNbytes.png

With no surprise, the pure Java EE implementation without any execution framework provides still the smallest executable. However, Haskell Snap (8MB) came in third after Go (6 MB). Looking at the size of the Docker image, the Go implementation is by far the smallest one (10 MB). This is due to the usage of Alpine as base image.

Weight of Time

IMHO there are two interesting characteristic numbers regarding time: First the build time of a service, second the startup time. This diagram shows the result of the measurements:

times.png

The Go implementation has the shortest build time. The startup time is the same as the Haskell Snap implementation, which probably consists mainly of the startup of the docker container. The Java based implementations are significantly slower.

To sum up

For simple web services Go provides a lightweight alternative with fast startup times und small memory consumption.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s