Skip to content

Instantly share code, notes, and snippets.

@kellabyte
Last active December 31, 2015 19:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kellabyte/8032308 to your computer and use it in GitHub Desktop.
Save kellabyte/8032308 to your computer and use it in GitHub Desktop.

OSX i7-3720QM CPU @ 2.60GHz go1.2 darwin/amd64

Performance doesn't increase with GOMAXPROCS it gets worse on OSX!

GOMAXPROCS=1
./websocket_client 1 100000
Sent 400000 in 2.389414969s for a rate of 167404/second

GOMAXPROCS=2
./websocket_client 2 100000
Sent 400000 in 6.219798526s for a rate of 64310/second <-- Lost 100K msgs/second!

GOMAXPROCS=3
./websocket_client 3 100000
Sent 400000 in 5.487955623s for a rate of 72886/second

GOMAXPROCS=4
./websocket_client 4 100000
Sent 400000 in 7.428882557s for a rate of 53843/second

2013 MBP retina

Confirmed again on someone elses OSX machine.

$ sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
$ go version
go version go1.2 darwin/amd64
$ ./client 1 100000
Sent 100000 in 896.185619ms for a rate of 111584/second
$ ./client 4 100000
Sent 400000 in 3.661056594s for a rate of 109258/second
$ GOMAXPROCS=4 ./client 1 100000
Sent 100000 in 923.826561ms for a rate of 108245/second
$ GOMAXPROCS=4 ./client 4 100000
Sent 400000 in 3.254549872s for a rate of 122904/second

Ubuntu 13.10, cpu is Intel Core i5-2500K

This one seems to scale with GOMAXPROCS!

$ go version
go version go1.2 linux/amd64
$ ./client 1 100000
Sent 100000 in 428.895171ms for a rate of 233157/second
$ ./client 4 100000
Sent 400000 in 1.79000027s for a rate of 223463/second
$ GOMAXPROCS=4 ./client 1 100000
Sent 100000 in 454.46171ms for a rate of 220040/second
$ GOMAXPROCS=4 ./client 4 100000
Sent 400000 in 700.25884ms for a rate of 571217/second

2.2GHz dual core Ivy Bridge FreeBSD 10.0rc1 Go 1.2

GOMAXPROCS=1:
./client 4 100000
Sent 400000 in 2.723452743s for a rate of 146872/second

GOMAXPROCS=2:
./client 4 100000
Sent 400000 in 3.107706227s for a rate of 128712/second

GOMAXPROCS=3:
./client 4 100000
Sent 400000 in 1.903976998s for a rate of 210086/second

GOMAXPROCS=4:
./client 4 100000
Sent 400000 in 1.736387681s for a rate of 230363/second

I did additional tests to figure out if the OSX problem is on the client or on the server side. It seems it is on the server side.

I know this isn't a localhost issue because I have a C based HTTP server that can do 500,000 HTTP requests/second on this machine over localhost with the much bulkier HTTP protocol.

Ubuntu server and OSX client over GbE LAN

Server: Ubuntu AMD Phenom(tm) 9150e Quad-Core Processor
Client: OSX i7-3720QM CPU @ 2.60GHz
GOMAXPROCS=4 on both client and server

./websocket_client 4 400000
Sent 1600000 in 3.354864357s for a rate of 476919/second

OSX server and Ubuntu client over GbE LAN

The OSX machine never goes above 115% CPU so the other 3 cores aren't used much.

Server: OSX i7-3720QM CPU @ 2.60GHz    
Client: Ubuntu AMD Phenom(tm) 9150e Quad-Core Processor    
GOMAXPROCS=4 on both client and server

./websocket_client 4 400000
Sent 1600000 in 7.687288138s for a rate of 208135/second
package main
import (
"log"
"code.google.com/p/go.net/websocket"
"sync"
"os"
"strconv"
"sync/atomic"
"fmt"
"time"
"runtime"
)
var wait sync.WaitGroup
var requests int
var completed int64
func main() {
fmt.Printf("GOMAXPROCS=%d\n", runtime.GOMAXPROCS(0))
clients, _ := strconv.Atoi(os.Args[1])
requests, _ = strconv.Atoi(os.Args[2])
start := time.Now()
for i:= 0; i< clients; i++ {
wait.Add(1)
go CreateClient()
}
wait.Wait()
elapsed := time.Since(start)
rate := float64(completed) / elapsed.Seconds()
fmt.Printf("Sent %d in %s for a rate of %d/second\n", completed, elapsed, int(rate))
}
func CreateClient() {
defer wait.Done()
ws, err := websocket.Dial("ws://localhost:8080/echo", "", "http://localhost/")
if err != nil {
log.Fatal(err)
}
message := []byte("hello, world!")
for i := 0; i < requests; i++ {
_, err = ws.Write(message)
if err != nil {
log.Fatal(err)
}
atomic.AddInt64(&completed, 1)
}
}
package main
import (
"code.google.com/p/go.net/websocket"
"net/http"
"fmt"
"log"
"runtime"
)
func main() {
fmt.Printf("GOMAXPROCS=%d\n", runtime.GOMAXPROCS(0))
fmt.Println("Listening")
http.Handle("/echo", websocket.Handler(echoHandler))
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
func echoHandler(ws *websocket.Conn) {
msg := make([]byte, 512)
var err error
for {
_, err = ws.Read(msg)
if err != nil {
log.Println(err)
//ws.Close()
break
}
//fmt.Printf("[Server]\tReceive: %s\n", msg[:n])
}
/*
_, err2 := ws.Write(msg[:n])
if err2 != nil {
log.Fatal(err2)
}
*/
//fmt.Printf("[Server]\tSend: %s\n", msg[:m])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment