func benchmarkCallsN(b *testing.B, c benchmarkConfig) { var ( clients []*Channel servers []*Channel ) lt := newLatencyTracker() if c.numBytes == 0 { c.numBytes = 100 } data := testutils.RandBytes(c.numBytes) // Set up clients and servers. for i := 0; i < c.numServers; i++ { servers = append(servers, setupServer(b)) } for i := 0; i < c.numClients; i++ { clients = append(clients, testutils.NewClient(b, nil)) for _, s := range servers { clients[i].Peers().Add(s.PeerInfo().HostPort) // Initialize a connection ctx, cancel := NewContext(50 * time.Millisecond) assert.NoError(b, clients[i].Ping(ctx, s.PeerInfo().HostPort), "Initial ping failed") cancel() } } // Make calls from clients to the servers call := func(sc *SubChannel) { ctx, cancel := NewContext(50 * time.Millisecond) start := time.Now() _, _, _, err := raw.CallSC(ctx, sc, "echo", nil, data) duration := time.Since(start) cancel() if assert.NoError(b, err, "Call failed") { lt.addLatency(duration) } } reqsLeft := testutils.Decrementor(c.numCalls) clientWorker := func(client *Channel, clientNum, workerNum int) { sc := client.GetSubChannel(benchService) for reqsLeft() { call(sc) } } clientRunner := func(client *Channel, clientNum int) { testutils.RunN(c.workersPerClient, func(i int) { clientWorker(client, clientNum, i) }) } lt.reset() defer lt.report(b) b.ResetTimer() testutils.RunN(c.numClients, func(i int) { clientRunner(clients[i], i) }) }
func benchmarkRelay(b *testing.B, p benchmarkParams) { b.SetBytes(int64(p.requestSize)) b.ReportAllocs() services := make(map[string][]string) servers := make([]benchmark.Server, p.servers) for i := range servers { servers[i] = benchmark.NewServer( benchmark.WithServiceName("svc"), benchmark.WithRequestSize(p.requestSize), benchmark.WithExternalProcess(), ) defer servers[i].Close() services["svc"] = append(services["svc]"], servers[i].HostPort()) } relay, err := benchmark.NewRealRelay(services) require.NoError(b, err, "Failed to create relay") defer relay.Close() clients := make([]benchmark.Client, p.clients) for i := range clients { clients[i] = benchmark.NewClient([]string{relay.HostPort()}, benchmark.WithServiceName("svc"), benchmark.WithRequestSize(p.requestSize), benchmark.WithExternalProcess(), benchmark.WithTimeout(10*time.Second), ) defer clients[i].Close() require.NoError(b, clients[i].Warmup(), "Warmup failed") } quantileVals := []float64{0.50, 0.95, 0.99, 1.0} quantiles := make([]*quantile.Stream, p.clients) for i := range quantiles { quantiles[i] = quantile.NewTargeted(quantileVals...) } wc := newWorkerControl(p.clients) dec := testutils.Decrementor(b.N) for i, c := range clients { go func(i int, c benchmark.Client) { // Do a warm up call. c.RawCall(1) wc.WorkerStart() defer wc.WorkerDone() for { tokens := dec.Multiple(200) if tokens == 0 { break } durations, err := c.RawCall(tokens) if err != nil { b.Fatalf("Call failed: %v", err) } for _, d := range durations { quantiles[i].Insert(float64(d)) } } }(i, c) } var started time.Time wc.WaitForStart(func() { b.ResetTimer() started = time.Now() }) wc.WaitForEnd() duration := time.Since(started) fmt.Printf("\nb.N: %v Duration: %v RPS = %0.0f\n", b.N, duration, float64(b.N)/duration.Seconds()) // Merge all the quantiles into 1 for _, q := range quantiles[1:] { quantiles[0].Merge(q.Samples()) } for _, q := range quantileVals { fmt.Printf(" %0.4f = %v\n", q, time.Duration(quantiles[0].Query(q))) } fmt.Println() }