From: Dmitriy Vyukov Date: Mon, 20 Aug 2012 17:27:52 +0000 (+0400) Subject: net: add TCP benchmarks X-Git-Tag: go1.1rc2~2618 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=922056d410bd8b1f75a7f6ea2b8664f98e574c2f;p=gostls13.git net: add TCP benchmarks 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 --- diff --git a/src/pkg/net/tcp_test.go b/src/pkg/net/tcp_test.go new file mode 100644 index 0000000000..53daf5b099 --- /dev/null +++ b/src/pkg/net/tcp_test.go @@ -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 + } +}