Skip to content

Commit 85b4950

Browse files
josharianzx2c4
authored andcommitted
device: add latency and throughput benchmarks
These obviously don't perfectly capture real world performance, in which syscalls and network links have a significant impact. Nevertheless, they capture some of the internal performance factors, and they're easy and convenient to work with. Hat tip to Avery Pennarun for help designing the throughput benchmark. Signed-off-by: Josh Bleecher Snyder <[email protected]>
1 parent 8a30415 commit 85b4950

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

device/device_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"io"
1313
"net"
1414
"sync"
15+
"sync/atomic"
1516
"testing"
1617
"time"
1718

@@ -281,3 +282,61 @@ func randDevice(t *testing.T) *Device {
281282
device.SetPrivateKey(sk)
282283
return device
283284
}
285+
286+
func BenchmarkLatency(b *testing.B) {
287+
pair := genTestPair(b)
288+
289+
// Establish a connection.
290+
pair.Send(b, Ping, nil)
291+
pair.Send(b, Pong, nil)
292+
293+
b.ResetTimer()
294+
for i := 0; i < b.N; i++ {
295+
pair.Send(b, Ping, nil)
296+
pair.Send(b, Pong, nil)
297+
}
298+
}
299+
300+
func BenchmarkThroughput(b *testing.B) {
301+
pair := genTestPair(b)
302+
303+
// Establish a connection.
304+
pair.Send(b, Ping, nil)
305+
pair.Send(b, Pong, nil)
306+
307+
// Measure how long it takes to receive b.N packets,
308+
// starting when we receive the first packet.
309+
var recv uint64
310+
var elapsed time.Duration
311+
var wg sync.WaitGroup
312+
wg.Add(1)
313+
go func() {
314+
defer wg.Done()
315+
var start time.Time
316+
for {
317+
<-pair[0].tun.Inbound
318+
new := atomic.AddUint64(&recv, 1)
319+
if new == 1 {
320+
start = time.Now()
321+
}
322+
// Careful! Don't change this to else if; b.N can be equal to 1.
323+
if new == uint64(b.N) {
324+
elapsed = time.Since(start)
325+
return
326+
}
327+
}
328+
}()
329+
330+
// Send packets as fast as we can until we've received enough.
331+
ping := tuntest.Ping(pair[0].ip, pair[1].ip)
332+
pingc := pair[1].tun.Outbound
333+
var sent uint64
334+
for atomic.LoadUint64(&recv) != uint64(b.N) {
335+
sent++
336+
pingc <- ping
337+
}
338+
wg.Wait()
339+
340+
b.ReportMetric(float64(elapsed)/float64(b.N), "ns/op")
341+
b.ReportMetric(1-float64(b.N)/float64(sent), "packet-loss")
342+
}

0 commit comments

Comments
 (0)