Hi,
Can someone help me figure out why the performance (request rate)
of this program goes down when I add more gorutines?
$ ./gb -duration 15s -parallel 5 http://nginx
Running 5 parallel clients for 15s...
Requests: 217998
Rate: 14533.2/s
Bytes: 133414776
Code[200]: 217998
$ ./gb -duration 15s -parallel 20 http://nginx
Running 20 parallel clients for 15s...
Requests: 155150
Rate: 10343.3/s
Bytes: 94951800
Code[200]: 155150
--
Valentin
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
package main
import (
"flag"
"fmt"
"io"
"net"
"net/http"
"os"
"runtime"
"runtime/pprof"
"time"
)
type stats struct {
req int
err int
rerr int
bytes int
code map[int]int
}
func bench(url string, compress bool, timeout time.Duration, done chan
struct{}, result chan stats) {
s := stats{}
s.code = make(map[int]int)
transport := &http.Transport{
DisableCompression: !compress,
TLSHandshakeTimeout: timeout,
DialContext: (&net.Dialer{
Timeout: timeout,
DualStack: true,
}).DialContext,
}
client := &http.Client{
Transport: transport,
Timeout: timeout,
}
written := 0
buf := make([]byte, 10*1024)
LOOP:
for {
s.req++
resp, err := client.Get(url)
if err != nil {
fmt.Println(err)
s.err++
} else {
s.code[resp.StatusCode]++
for {
written, err = resp.Body.Read(buf)
s.bytes += written
if err != nil {
break
}
}
if err != nil && err != io.EOF {
fmt.Println(err)
s.rerr++
}
resp.Body.Close()
}
select {
case <-done:
break LOOP
default:
}
}
result <- s
}
func main() {
var compression = flag.Bool("compression", true, "use HTTP compression")
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to
file")
var duration = flag.Duration("duration", 15*time.Second, "test
duration")
var memprofile = flag.String("memprofile", "", "write memory profile to
file")
var parallel = flag.Int("parallel", 20, "number of parallel client
connections")
var timeout = flag.Duration("timeout", 10*time.Second, "request
timeout")
flag.Parse()
url := flag.Arg(0)
if url == "" {
fmt.Println("No url given")
os.Exit(1)
}
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
fmt.Println("Could not create cpu profile:", err)
os.Exit(1)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
done := make(chan struct{})
result := make(chan stats)
fmt.Printf("Running %d parallel clients for %v...\n", *parallel,
*duration)
for i := 0; i < *parallel; i++ {
go bench(url, *compression, *timeout, done, result)
}
time.Sleep(*duration)
close(done)
total := stats{}
total.code = make(map[int]int)
for i := 0; i < *parallel; i++ {
s := <-result
total.req += s.req
total.err += s.err
total.rerr += s.rerr
total.bytes += s.bytes
for k, v := range s.code {
total.code[k] += v
}
}
fmt.Println("Requests:", total.req)
fmt.Printf("Rate: %.1f/s\n", float64(total.req)/duration.Seconds())
fmt.Println("Bytes:", total.bytes)
if total.err > 0 {
fmt.Println("Errors:", total.err)
}
if total.rerr > 0 {
fmt.Println("Read errors:", total.rerr)
}
for k, v := range total.code {
fmt.Printf("Code[%d]: %d\n", k, v)
}
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
fmt.Println("Could not create memory profile: ", err)
}
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
fmt.Println("could not write memory profile: ", err)
}
f.Close()
}
}