]> Cypherpunks repositories - gostls13.git/commitdiff
net: add TCP benchmarks
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 20 Aug 2012 17:27:52 +0000 (21:27 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 20 Aug 2012 17:27:52 +0000 (21:27 +0400)
Current results on linux_amd64, 8 HT cores @2.4GHz:
BenchmarkTCPOneShot    10000     194037 ns/op
BenchmarkTCPOneShot-2    20000      93641 ns/op
BenchmarkTCPOneShot-4    20000      94039 ns/op
BenchmarkTCPOneShot-8    20000      94667 ns/op
BenchmarkTCPOneShot-16    10000     301924 ns/op
BenchmarkTCPOneShotTimeout    10000     193264 ns/op
BenchmarkTCPOneShotTimeout-2    20000      98247 ns/op
BenchmarkTCPOneShotTimeout-4    20000      94442 ns/op
BenchmarkTCPOneShotTimeout-8    20000      95297 ns/op
BenchmarkTCPOneShotTimeout-16    10000     307970 ns/op
BenchmarkTCPPersistent    50000      52050 ns/op
BenchmarkTCPPersistent-2   100000      29452 ns/op
BenchmarkTCPPersistent-4   100000      28823 ns/op
BenchmarkTCPPersistent-8    50000      30473 ns/op
BenchmarkTCPPersistent-16    10000     311777 ns/op
BenchmarkTCPPersistentTimeout    50000      32574 ns/op
BenchmarkTCPPersistentTimeout-2    50000      29723 ns/op
BenchmarkTCPPersistentTimeout-4   100000      28592 ns/op
BenchmarkTCPPersistentTimeout-8   100000      28997 ns/op
BenchmarkTCPPersistentTimeout-16    10000     314354 ns/op

R=golang-dev, alex.brainman, dave, mikioh.mikioh, r, iant, bradfitz, iant
CC=golang-dev
https://golang.org/cl/6458128

src/pkg/net/tcp_test.go [new file with mode: 0644]

diff --git a/src/pkg/net/tcp_test.go b/src/pkg/net/tcp_test.go
new file mode 100644 (file)
index 0000000..53daf5b
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+       "runtime"
+       "testing"
+       "time"
+)
+
+func BenchmarkTCPOneShot(b *testing.B) {
+       benchmarkTCP(b, false, false)
+}
+
+func BenchmarkTCPOneShotTimeout(b *testing.B) {
+       benchmarkTCP(b, false, true)
+}
+
+func BenchmarkTCPPersistent(b *testing.B) {
+       benchmarkTCP(b, true, false)
+}
+
+func BenchmarkTCPPersistentTimeout(b *testing.B) {
+       benchmarkTCP(b, true, true)
+}
+
+func benchmarkTCP(b *testing.B, persistent, timeout bool) {
+       const msgLen = 512
+       conns := b.N
+       numConcurrent := runtime.GOMAXPROCS(-1) * 16
+       msgs := 1
+       if persistent {
+               conns = numConcurrent
+               msgs = b.N / conns
+               if msgs == 0 {
+                       msgs = 1
+               }
+               if conns > b.N {
+                       conns = b.N
+               }
+       }
+       sendMsg := func(c Conn, buf []byte) bool {
+               n, err := c.Write(buf)
+               if n != len(buf) || err != nil {
+                       b.Logf("Write failed: %v", err)
+                       return false
+               }
+               return true
+       }
+       recvMsg := func(c Conn, buf []byte) bool {
+               for read := 0; read != len(buf); {
+                       n, err := c.Read(buf)
+                       read += n
+                       if err != nil {
+                               b.Logf("Read failed: %v", err)
+                               return false
+                       }
+               }
+               return true
+       }
+       ln, err := Listen("tcp", "127.0.0.1:0")
+       if err != nil {
+               b.Fatalf("Listen failed: %v", err)
+       }
+       defer ln.Close()
+       // Acceptor.
+       go func() {
+               for {
+                       c, err := ln.Accept()
+                       if err != nil {
+                               break
+                       }
+                       // Server connection.
+                       go func(c Conn) {
+                               defer c.Close()
+                               if timeout {
+                                       c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
+                               }
+                               var buf [msgLen]byte
+                               for m := 0; m < msgs; m++ {
+                                       if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
+                                               break
+                                       }
+                               }
+                       }(c)
+               }
+       }()
+       sem := make(chan bool, numConcurrent)
+       for i := 0; i < conns; i++ {
+               sem <- true
+               // Client connection.
+               go func() {
+                       defer func() {
+                               <-sem
+                       }()
+                       c, err := Dial("tcp", ln.Addr().String())
+                       if err != nil {
+                               b.Logf("Dial failed: %v", err)
+                               return
+                       }
+                       defer c.Close()
+                       if timeout {
+                               c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
+                       }
+                       var buf [msgLen]byte
+                       for m := 0; m < msgs; m++ {
+                               if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
+                                       break
+                               }
+                       }
+               }()
+       }
+       for i := 0; i < cap(sem); i++ {
+               sem <- true
+       }
+}