Порівняння продуктивності праці D і Go для веб

Доброго часу доби, хабр!

Так як мені скоро доведеться розробляти веб-додаток, а писати на интерпретирумых мови як-то немає бажання, тим більше, що є такі МП як D і Go, виникло бажання порівняти їх продуктивність при роботі з веб (в мережі не знайшов тестів, які були б свіжими). Для D це vibe.d, а для Go, як я зрозумів, не використовуються фреймворки. Так як Go я знаю менш ніж ніяк вирішив не випендрюватися: тестові програми просто віддають сторінку з деяким текстом (ні баз даних, ні складного роутінга, ні зображень).

Навантаження давалася з допомогою Apache Benchmark.



Додаток D це стандартний vibe додаток, нас будуть цікавити тільки
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);
}
views/index.dt
html
head
body
h1 Привіт, Хабр!

p D is a systems programming language with C-like syntax.

= var
збірка:
dub build --build=release


В Go додатку нас цікавлять відповідні файли
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);
}

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>

збірка:
go build site_test_go.go


Навантаження:
ab -c200 -n50000 http://localhost:8101/
(8100 для site_test_go)

Почнемо
Apache Benchmark
Трохи різний код index файлів був зроблений для відповідності Document Length (мабуть vibe передає щось в заголовку відповіді)
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 7 3.5 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 9 2.3 211
 
Waiting: 1 7 7 2.4 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)
 



Пам'ять
Замір проводився за допомогою
gnome-system-monitor

dlang golang
до першого запиту memory: 680.0 KiB
virtual: 907.5 MiB
resident: 10.2 MiB
writable: 343.3 MiB
shared: 9.5 MiB
memory: 888.0 KiB
virtual: 110.8 MiB
resident: 5.2 MiB
writable: 35.7 MiB
shared: 4.4 MiB
після запуску ab memory: 19.2 MiB
virtual: 9.5 GiB
resident: 28.7 MiB
writable: 9.0 GiB
shared: 9.6 MiB
memory: 6.5 MiB
virtual: 1.3 GiB
resident: 12.5 MiB
writable: 1.0 GiB
shared: 5.9 MiB


Завантаження процесора
Замір проводився за допомогою
gnome-system-monitor

dlang golang


Версії
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

Висновки
Продуктивність інструментів практично не відрізняється (чому я здивований, насправді).
Засмутило споживання пам'яті у D: практично в 3 рази більше ніж у Go.
Виходячи з графіків завантаженості процесора, можна зробити висновок: планувальник завдань в Go влаштований краще — відразу розподіляє навантаження на ядра порівну, але в середньому завантаження ЦП у D нижче.
Варто відзначити, що додаток D компілюється довше (для веб розробки це може бути неприємним моментом).

PS: це мій перший експеримент з продуктивністю веб (взагалі поки не добре з веб знаком), так що буду дуже радий, якщо ви вкажіть на помилки в способі вимірювання та/або початкових умовах =)

для любителів мови Dгрупа в ВК
група в Telegram
група в Telegram (англ.)


UPD:
Ось тут я зрозумів, напевно, самоую велику помилку, у всій цій перевірці. vibe-d використовує libevent2 і в цьому тесті впирається продуктивністю саме в нього (судячи за результатами valgrind/callgrind). А go, як я зрозумів, має власну реалізацію event-loop'а, причому сторонні бібліотеки навіть краще по продуктивності ніж з коробки (не зрозумів як скомпілювати go, щоб символи були у виконуваному файлі для valgrind,
go build -ldflags "-w" -gcflags "-N -l"
не допомогло).

Але все-одно, тест конфігурацій «з коробки», особисто для мене був цікавий.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.