v2 / vlib / goroutines / examples / goroutine_benchmark.go
119 lines · 94 sloc · 2.74 KB · e21acca549c0df34c98beb389088dbf7cee4c4d0
Raw
1// Goroutine benchmark in Go – equivalent to goroutine_benchmark.v.
2//
3// Tests:
4// 1. Goroutine creation + completion (fan-out/fan-in via unbuffered channel)
5// 2. Channel ping-pong between two goroutines
6// 3. Many goroutines contending on a single channel
7//
8// Run: go run goroutine_benchmark.go
9package main
10
11import (
12 "fmt"
13 "time"
14)
15
16// ---------------------------------------------------------------------------
17// Benchmark 1 – fan-out / fan-in (unbuffered channel)
18// ---------------------------------------------------------------------------
19
20func benchFanOutFanIn(n int) {
21 c := make(chan int) // unbuffered, matching V benchmark
22
23 start := time.Now()
24
25 for i := 0; i < n; i++ {
26 go func() {
27 c <- 1
28 }()
29 }
30
31 for i := 0; i < n; i++ {
32 <-c
33 }
34
35 elapsed := time.Since(start)
36 fmt.Printf("fan-out/fan-in %d goroutines: %d us (%d ns/goroutine)\n",
37 n, elapsed.Microseconds(), elapsed.Nanoseconds()/int64(n))
38}
39
40// ---------------------------------------------------------------------------
41// Benchmark 2 – channel ping-pong
42// ---------------------------------------------------------------------------
43
44func benchPingPong(n int) {
45 c1 := make(chan int, 1)
46 c2 := make(chan int, 1)
47
48 go func() {
49 for i := 0; i < n; i++ {
50 val := <-c1
51 c2 <- val + 1
52 }
53 }()
54
55 start := time.Now()
56
57 val := 0
58 for i := 0; i < n; i++ {
59 c1 <- val
60 val = <-c2
61 }
62
63 elapsed := time.Since(start)
64 fmt.Printf("ping-pong %d round-trips: %d us (%d ns/round-trip)\n",
65 n, elapsed.Microseconds(), elapsed.Nanoseconds()/int64(n))
66}
67
68// ---------------------------------------------------------------------------
69// Benchmark 3 – contended channel (many producers, one consumer)
70// ---------------------------------------------------------------------------
71
72func benchContendedChannel(numProducers int, msgsPerProducer int) {
73 total := numProducers * msgsPerProducer
74 c := make(chan int, 64)
75
76 start := time.Now()
77
78 for p := 0; p < numProducers; p++ {
79 go func() {
80 for i := 0; i < msgsPerProducer; i++ {
81 c <- i
82 }
83 }()
84 }
85
86 for i := 0; i < total; i++ {
87 <-c
88 }
89
90 elapsed := time.Since(start)
91 fmt.Printf("contended chan %d producers x %d msgs: %d us (%d ns/msg)\n",
92 numProducers, msgsPerProducer,
93 elapsed.Microseconds(), elapsed.Nanoseconds()/int64(total))
94}
95
96// ---------------------------------------------------------------------------
97// Main
98// ---------------------------------------------------------------------------
99
100func main() {
101 fmt.Println("=== Go Goroutine Benchmark ===")
102 fmt.Println()
103
104 benchFanOutFanIn(10)
105 benchFanOutFanIn(50)
106 benchFanOutFanIn(100)
107 benchFanOutFanIn(500)
108
109 fmt.Println()
110 benchPingPong(1000)
111 benchPingPong(10000)
112 benchPingPong(100000)
113
114 fmt.Println()
115 benchContendedChannel(4, 1000)
116 benchContendedChannel(10, 1000)
117
118 fmt.Println()
119}
120