mirror of
https://github.com/golang/go
synced 2024-10-01 01:18:32 -06:00
expvar: Add benchmarks for perf sensitive operations
These benchmarks are only for functions commonly used in loops. The other functions are typically used for inspection or setup and thus are not performance sensitive. Change-Id: I8d0a0ba2d8234ecacb40fa3aa9077bf93c8fe89c Reviewed-on: https://go-review.googlesource.com/3680 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
cb4b28e013
commit
fc22fb8f0c
@ -7,8 +7,11 @@ package expvar
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http/httptest"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -47,6 +50,26 @@ func TestInt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIntAdd(b *testing.B) {
|
||||
var v Int
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
v.Add(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkIntSet(b *testing.B) {
|
||||
var v Int
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
v.Set(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestFloat(t *testing.T) {
|
||||
RemoveAll()
|
||||
reqs := NewFloat("requests-float")
|
||||
@ -73,6 +96,26 @@ func TestFloat(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFloatAdd(b *testing.B) {
|
||||
var f Float
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
f.Add(1.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkFloatSet(b *testing.B) {
|
||||
var f Float
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
f.Set(1.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
RemoveAll()
|
||||
name := NewString("my-name")
|
||||
@ -90,6 +133,16 @@ func TestString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStringSet(b *testing.B) {
|
||||
var s String
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
s.Set("red")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMapCounter(t *testing.T) {
|
||||
RemoveAll()
|
||||
colors := NewMap("bike-shed-colors")
|
||||
@ -130,6 +183,38 @@ func TestMapCounter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMapSet(b *testing.B) {
|
||||
m := new(Map).Init()
|
||||
|
||||
v := new(Int)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
m.Set("red", v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMapAddSame(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
m := new(Map).Init()
|
||||
m.Add("red", 1)
|
||||
m.Add("red", 1)
|
||||
m.Add("red", 1)
|
||||
m.Add("red", 1)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMapAddDifferent(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
m := new(Map).Init()
|
||||
m.Add("red", 1)
|
||||
m.Add("blue", 1)
|
||||
m.Add("green", 1)
|
||||
m.Add("yellow", 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFunc(t *testing.T) {
|
||||
RemoveAll()
|
||||
var x interface{} = []string{"a", "b"}
|
||||
@ -165,3 +250,135 @@ func TestHandler(t *testing.T) {
|
||||
t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRealworldExpvarUsage(b *testing.B) {
|
||||
var (
|
||||
bytesSent Int
|
||||
bytesRead Int
|
||||
)
|
||||
|
||||
// The benchmark creates GOMAXPROCS client/server pairs.
|
||||
// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
|
||||
// The benchmark stresses concurrent reading and writing to the same connection.
|
||||
// Such pattern is used in net/http and net/rpc.
|
||||
|
||||
b.StopTimer()
|
||||
|
||||
P := runtime.GOMAXPROCS(0)
|
||||
N := b.N / P
|
||||
W := 1000
|
||||
|
||||
// Setup P client/server connections.
|
||||
clients := make([]net.Conn, P)
|
||||
servers := make([]net.Conn, P)
|
||||
ln, err := net.Listen("tcp", laddr)
|
||||
if err != nil {
|
||||
b.Fatalf("Listen failed: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
for p := 0; p < P; p++ {
|
||||
s, err := ln.Accept()
|
||||
if err != nil {
|
||||
b.Errorf("Accept failed: %v", err)
|
||||
return
|
||||
}
|
||||
servers[p] = s
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
for p := 0; p < P; p++ {
|
||||
c, err := net.Dial("tcp", ln.Addr().String())
|
||||
if err != nil {
|
||||
b.Fatalf("Dial failed: %v", err)
|
||||
}
|
||||
clients[p] = c
|
||||
}
|
||||
<-done
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(4 * P)
|
||||
for p := 0; p < P; p++ {
|
||||
// Client writer.
|
||||
go func(c net.Conn) {
|
||||
defer wg.Done()
|
||||
var buf [1]byte
|
||||
for i := 0; i < N; i++ {
|
||||
v := byte(i)
|
||||
for w := 0; w < W; w++ {
|
||||
v *= v
|
||||
}
|
||||
buf[0] = v
|
||||
n, err := c.Write(buf[:])
|
||||
if err != nil {
|
||||
b.Errorf("Write failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
bytesSent.Add(int64(n))
|
||||
}
|
||||
}(clients[p])
|
||||
|
||||
// Pipe between server reader and server writer.
|
||||
pipe := make(chan byte, 128)
|
||||
|
||||
// Server reader.
|
||||
go func(s net.Conn) {
|
||||
defer wg.Done()
|
||||
var buf [1]byte
|
||||
for i := 0; i < N; i++ {
|
||||
n, err := s.Read(buf[:])
|
||||
|
||||
if err != nil {
|
||||
b.Errorf("Read failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
bytesRead.Add(int64(n))
|
||||
pipe <- buf[0]
|
||||
}
|
||||
}(servers[p])
|
||||
|
||||
// Server writer.
|
||||
go func(s net.Conn) {
|
||||
defer wg.Done()
|
||||
var buf [1]byte
|
||||
for i := 0; i < N; i++ {
|
||||
v := <-pipe
|
||||
for w := 0; w < W; w++ {
|
||||
v *= v
|
||||
}
|
||||
buf[0] = v
|
||||
n, err := s.Write(buf[:])
|
||||
if err != nil {
|
||||
b.Errorf("Write failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
bytesSent.Add(int64(n))
|
||||
}
|
||||
s.Close()
|
||||
}(servers[p])
|
||||
|
||||
// Client reader.
|
||||
go func(c net.Conn) {
|
||||
defer wg.Done()
|
||||
var buf [1]byte
|
||||
for i := 0; i < N; i++ {
|
||||
n, err := c.Read(buf[:])
|
||||
|
||||
if err != nil {
|
||||
b.Errorf("Read failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
bytesRead.Add(int64(n))
|
||||
}
|
||||
c.Close()
|
||||
}(clients[p])
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user