📜 ⬆️ ⬇️

Comparing D and Go performance for web

Good day, Habr!

Since I will soon have to develop a web application, I don’t have a desire to write in interpretable languages, especially since there are some PLs like D and Go, there was a desire to compare their performance when working with the web (I didn’t find tests in the network that would be fresh). For D, this is vibe.d, and for Go, as I understand it, no frameworks are used. As I know Go, I have decided not to show off with less than “no way”: test applications simply give up a page with some text (no databases, no complex routing, no images).

Load was given using Apache Benchmark.
')


The D app is a standard vibe app, we will only be interested
source / app.d
import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.options |= HTTPServerOption.distribute; //    vibe  settings.port = 8101; settings.bindAddresses = ["::1", "127.0.0.1"]; listenHTTP(settings, &index); } void index(HTTPServerRequest req, HTTPServerResponse res) { auto var = "hello habr"; res.render!("index.dt",var); } 
and
views / index.dt
 html head body h1 , ! p D is a systems programming language with C-like syntax. = var 
build: dub build --build=release

In the Go application we are interested in the corresponding files.
site_test_go.go
 package main import ( "html/template" "net/http" ) type Page struct { Var string } func indexViewer(w http.ResponseWriter, r *http.Request) { p := Page{Var:"hello habr"} t, _ := template.ParseFiles("index.html") t.Execute(w, p) } func main() { http.HandleFunc("/", indexViewer); http.ListenAndServe(":8100", nil); } 

and
index.html
 <h1>, !</h1> <p>Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.</p> <div> {{.Var}} </div> 

build: go build site_test_go.go

Load: ab -c200 -n50000 http://localhost:8101/ (8100 for site_test_go)

Let's start

Apache benchmark

A slightly different code of the index files was made to match the Document Length (apparently the vibe conveys something in the response header)
dlanggolang
Server Software: vibe.d/0.7.28
Server Hostname: localhost
Server Port: 8101

Document Path: /
Document Length: 182 bytes

Concurrency Level: 200
Time taken for tests: 4.481 seconds
Complete requests: 50000
Failed requests: 0
Total transferred: 16450000 bytes
HTML transferred: 9100000 bytes
Requests per second: 11157.90 [#/sec] (mean)
Time per request: 17.925 [ms] (mean)
Time per request: 0.090 [ms] (mean, across all concurrent requests)
Transfer rate: 3584.91 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 33.2 7 1009
Processing: 2 10 3.7 9 207
Waiting: 1 8 3.5 7 205
Total: 3 18 33.4 17 1020

Percentage of the requests served within a certain time (ms)
50% 17
66% 18
75% 18
80% 18
90% 19
95% 23
98% 29
99% 30
100% 1020 (longest request)

Server Software:
Server Hostname: localhost
Server Port: 8100

Document Path: /
Document Length: 182 bytes

Concurrency Level: 200
Time taken for tests: 4.263 seconds
Complete requests: 50000
Failed requests: 0
Total transferred: 14950000 bytes
HTML transferred: 9100000 bytes
Requests per second: 11728.36 [#/sec] (mean)
Time per request: 17.053 [ms] (mean)
Time per request: 0.085 [ms] (mean, across all concurrent requests)
Transfer rate: 3424.59 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 14.9 7 1011
Processing: 2 9 2.3 9 211
Waiting: 1 7 2.4 7 210
Total: 10 17 15.1 16 1020

Percentage of the requests served within a certain time (ms)
50% 16
66% 17
75% 18
80% 18
90% 19
95% 20
98% 21
99% 22
100% 1020 (longest request)



Memory

Measurement was done using gnome-system-monitor
dlanggolang
before the first requestmemory: 680.0KiB
virtual: 907.5MiB
resident: 10.2MiB
writable: 343.3MiB
shared: 9.5MiB
memory: 888.0KiB
virtual: 110.8MiB
resident: 5.2MiB
writable: 35.7MiB
shared: 4.4MiB
after running abmemory: 19.2MiB
virtual: 9.5GiB
resident: 28.7MiB
writable: 9.0GiB
shared: 9.6MiB
memory: 6.5MiB
virtual: 1.3GiB
resident: 12.5MiB
writable: 1.0GiB
shared: 5.9MiB


CPU load

Measurement was done using gnome-system-monitor
dlanggolang


Software Versions

apr-util-1.5.4-1.fc22.x86_64

DMD64 D Compiler v2.071.0
DUB version 0.9.25, built on May 22 2016
vibe 0.7.28

go version go1.5.4 linux / amd64

findings

The performance of the tools practically does not differ (which I am surprised, in fact).
Distressed memory consumption from D: almost 3 times more than Go.
Based on the processor load schedules, we can conclude: the task scheduler in Go is better structured - it immediately distributes the load on the cores equally, but on average, the CPU load is lower for D.
It should be noted that the application on D compiles longer (for web development this can be an unpleasant moment).

PS: this is my first experiment with the performance of the web (in general it’s not good with the web yet), so I’ll be very happy if you point out errors in the measurement method and / or initial conditions =)



UPD:
Here I understood, probably, the biggest mistake in all this checking. vibe-d uses libevent2 and in this test rests on the performance of it (judging by the results of valgrind / callgrind). And go, as I understand it, has its own event-loop implementation, and third-party libraries are even better in performance than out of the box (I didn't understand how to compile go, so that the characters were in the executable file for valgrind, go build -ldflags "-w" -gcflags "-N -l" did not help).

But anyway, the “out of the box” configuration test was interesting to me personally.

Source: https://habr.com/ru/post/303590/


All Articles