Fan vs Go Func

Table Of Contents

test script

 1func gen(nums ...int) <-chan int {
 2   out := make(chan int)
 3   go func() {
 4      for _, n := range nums {
 5         out <- n
 6      }
 7      close(out)
 8   }()
 9   return out
10}
11func sq(in <-chan int) <-chan int {
12   out := make(chan int)
13   go func() {
14      for n := range in {
15         out <- n * n
16      }
17      close(out)
18   }()
19   return out
20}
21
22func merge(cs ...<-chan int) <-chan int {
23   var wg sync.WaitGroup
24   out := make(chan int)
25
26   // Start an output goroutine for each input channel in cs.  output
27   // copies values from c to out until c is closed, then calls wg.Done.
28   output := func(c <-chan int) {
29      for n := range c {
30         out <- n
31      }
32      wg.Done()
33   }
34   wg.Add(len(cs))
35   for _, c := range cs {
36      go output(c)
37   }
38
39   // Start a goroutine to close out once all the output goroutines are
40   // done.  This must start after the wg.Add call.
41   go func() {
42      wg.Wait()
43      close(out)
44   }()
45   return out
46}
47
48func TestFan(t *testing.T) {
49   x := []int{0}
50   for i := 1; i < 10000; i++ {
51      x = append(x, i)
52   }
53   st := time.Now().UnixMicro()
54   c := gen(x...)
55
56   out := []<-chan int{}
57   for i := 0; i < 10; i++ {
58      out = append(out, sq(c))
59   }
60
61   // Consume the output.
62   for n := range merge(out...) {
63      fmt.Println(n) // 4 then 9, or 9 then 4
64   }
65   t1 := time.Now().UnixMicro() - st
66
67   fmt.Println("=======")
68   st = time.Now().UnixMicro()
69   var wg sync.WaitGroup
70   wg.Add(len(x))
71   for _, i := range x {
72      go func(x int) {
73         defer wg.Done()
74         fmt.Println(x * x)
75      }(i)
76   }
77   wg.Wait()
78   t2 := time.Now().UnixMicro() - st
79
80   fmt.Printf("===%d vs %d", t1, t2)
81   assert.Assert(t, t1 < t2)
82}
83
84// performace 1:4
85

Fxxk SSH
HTTP Method POST vs GET
comments powered by Disqus