Skip to content

Instantly share code, notes, and snippets.

@erikdubbelboer
Created October 11, 2019 09:31
Show Gist options
  • Select an option

  • Save erikdubbelboer/f723725ec2c5a04aec31097be1aeca91 to your computer and use it in GitHub Desktop.

Select an option

Save erikdubbelboer/f723725ec2c5a04aec31097be1aeca91 to your computer and use it in GitHub Desktop.
libdill vs go concurrency
$ GOMAXPROCS=1 go run test.go
400: 200.371937ms (1285)
400: 200.557002ms (1998)
400: 201.016092ms (1993)
400: 201.548925ms (1993)
800: 201.371267ms (2340)
800: 201.489716ms (3996)
800: 205.647786ms (3998)
800: 212.762004ms (3459)
832: 223.881178ms (4000)
1200: 218.261065ms (4604)
1200: 228.361347ms (4822)
1200: 242.339691ms (4840)
1200: 237.106709ms (5967)
1600: 232.599986ms (5211)
1600: 241.591029ms (6508)
1600: 248.229335ms (6405)
1600: 250.645088ms (6402)
1655: 247.676691ms (6405)
2000: 243.99667ms (7667)
2000: 257.26845ms (8004)
2000: 259.676307ms (8005)
2000: 258.15523ms (8002)
2400: 260.803964ms (7040)
2400: 263.346493ms (8773)
2400: 270.516326ms (9602)
2400: 271.058956ms (9603)
2435: 271.137592ms (7208)
2800: 269.263223ms (10719)
2800: 281.181331ms (9715)
2800: 282.178128ms (9890)
2800: 280.895995ms (11204)
3193: 279.78257ms (8679)
3200: 282.283139ms (12865)
3200: 291.619907ms (9638)
3200: 292.22178ms (10884)
3200: 293.265053ms (11520)
3600: 288.189127ms (10442)
3600: 300.098371ms (14401)
3600: 299.41196ms (10836)
3600: 302.394837ms (10867)
3942: 296.760366ms (14601)
4000: 305.790815ms (12138)
4000: 309.595006ms (12036)
4000: 307.226121ms (13318)
4000: 310.559451ms (14753)
4400: 306.093626ms (12896)
4400: 317.336548ms (13268)
4400: 315.589827ms (13268)
4400: 317.671076ms (13329)
4626: 319.180849ms (15735)
4800: 325.442857ms (14926)
4800: 331.493786ms (14820)
4800: 331.640781ms (14758)
4800: 334.349697ms (14404)
$ cc -ldill -o test test.c
$ ./test
400 200ms (1212)
400 200ms (1995)
400 201ms (2000)
400 202ms (1985)
699 202ms (2124)
800 201ms (3894)
800 203ms (3992)
800 206ms (3746)
800 206ms (4000)
1200 203ms (4733)
1200 204ms (5988)
1200 207ms (5699)
1200 206ms (6000)
1359 205ms (5757)
1600 202ms (7509)
1600 203ms (7797)
1600 206ms (7957)
1600 207ms (7580)
2000 204ms (8485)
2000 204ms (9995)
2000 204ms (9528)
2000 208ms (9273)
2021 207ms (10000)
2400 203ms (11273)
2400 203ms (11306)
2400 207ms (11851)
2400 206ms (12000)
2701 204ms (11717)
2800 203ms (13115)
2800 205ms (14000)
2800 206ms (13326)
2800 206ms (13304)
3200 206ms (14882)
3200 205ms (16000)
3200 205ms (15990)
3200 205ms (14418)
3348 206ms (15563)
3600 203ms (17454)
3600 204ms (18000)
3600 207ms (17984)
3600 208ms (16902)
3990 204ms (17554)
4000 203ms (19579)
4000 204ms (19096)
4000 204ms (19674)
4000 205ms (19907)
4400 206ms (21108)
4400 204ms (21015)
4400 205ms (21958)
4400 206ms (21076)
4608 205ms (21731)
4800 203ms (23156)
4800 205ms (23088)
4800 206ms (23529)
4800 208ms (22291)
#include <libdill.h>
#include <stdio.h>
#include <stdlib.h>
int connections = 0;
int duration = 0;
int count = 0;
void panic() {
perror(NULL);
exit(1);
}
coroutine void handler(int c) {
char buf[4];
while (1) {
if (brecv(c, buf, sizeof(buf), -1) != 0) {
panic();
}
msleep(now() + 200);
if (bsend(c, buf, 4, -1) != 0) {
panic();
}
}
}
coroutine void listener(int ln) {
while (1) {
int c = tcp_accept(ln, NULL, -1);
if (c == -1) {
panic();
}
go(handler(c));
}
}
coroutine void worker() {
struct ipaddr addr;
ipaddr_local(&addr, "127.0.0.1", 5555, 0);
int c = tcp_connect(&addr, -1);
if (c == -1) {
panic();
}
__atomic_add_fetch(&connections, 1, __ATOMIC_RELAXED);
char buf[4] = { 1, 2, 3, 4 };
while (1) {
int64_t start = now();
if (bsend(c, buf, 4, -1) != 0) {
panic();
return;
}
if (brecv(c, buf, sizeof(buf), -1) != 0) {
panic();
return;
}
int d = now() - start;
__atomic_add_fetch(&duration, d, __ATOMIC_RELAXED);
__atomic_add_fetch(&count, 1, __ATOMIC_RELAXED);
}
}
coroutine void startup() {
while (1) {
for (int i = 0; i < 400; i++) {
go(worker());
msleep(now() + 1);
}
msleep(now() + 4000);
}
}
int main() {
struct ipaddr addr;
ipaddr_local(&addr, "127.0.0.1", 5555, 0);
int ln = tcp_listen(&addr, 128);
if (ln == -1) {
panic();
}
go(listener(ln));
go(startup());
while (1) {
msleep(now() + 1000);
int n = __atomic_load_n(&connections, __ATOMIC_RELAXED);
int d = __atomic_exchange_n(&duration, 0, __ATOMIC_RELAXED);
int c = __atomic_exchange_n(&count, 0, __ATOMIC_RELAXED);
printf("% 5d %dms (%d)\n", n, d/c, c);
}
return 0;
}
package main
import (
"fmt"
"net"
"sync/atomic"
"time"
)
var (
duration = int64(0)
count = int64(0)
connections = int64(0)
)
func handler(c net.Conn) {
buff := make([]byte, 4)
for {
if _, err := c.Read(buff); err != nil {
panic(err)
}
time.Sleep(time.Millisecond * 200)
if _, err := c.Write(buff); err != nil {
panic(err)
}
}
}
func listener(ln net.Listener) {
for {
c, err := ln.Accept()
if err != nil {
panic(err)
}
go handler(c)
}
}
func worker() {
c, err := net.Dial("tcp", "127.0.0.1:5555")
if err != nil {
panic(err)
}
atomic.AddInt64(&connections, 1)
buff := []byte{1, 2, 3, 4}
for {
start := time.Now()
if _, err := c.Write(buff); err != nil {
panic(err)
}
if _, err := c.Read(buff); err != nil {
panic(err)
}
d := int64(time.Since(start))
atomic.AddInt64(&duration, d)
atomic.AddInt64(&count, 1)
}
}
func startup() {
for {
for i := 0; i < 400; i++ {
go worker()
time.Sleep(time.Millisecond)
}
time.Sleep(time.Second * 4)
}
}
func main() {
ln, err := net.Listen("tcp", "127.0.0.1:5555")
if err != nil {
panic(err)
}
go listener(ln)
go startup()
for {
time.Sleep(time.Second)
n := atomic.LoadInt64(&connections)
d := atomic.SwapInt64(&duration, 0)
c := atomic.SwapInt64(&count, 0)
if c > 0 {
fmt.Printf("% 5d: %v (%d)\n", n, time.Duration(d/c), c)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment