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.dimport 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)
dlang | golang |
---|
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
| dlang | golang |
---|
before the first request | memory: 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 ab | memory: 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
dlang | golang |
---|
 |  |
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.