Detail Go concurrency

  • 2020-11-03 22:29:25
  • OfStack

Support concurrent golang natural language level, very good language, sometimes our business development, with complex scenes, need for concurrent, will complete the concurrent multiple requests using coroutines group, when faced with a nested loop, also there is a context relationship need to transform for concurrent requests, will be before the time complexity of O (n ^ 2) instead of O (n) time complexity, does that also can step and time complexity into 1 to O (1) the & # 63; How to nest concurrency, how to write. Today, step by step analysis.

The serial execution

The time complexity is O(n^2) Not using concurrency The resulting execution time was 9s

//  The serial execution 
func SerializeRun() {
	start := time.Now()
	xx := []int{1, 2, 3}
	yy := []int{100, 200, 300}
	for _, x := range xx {
		for _, y := range yy {
			abc(x, y)
		}
	}
	fmt.Printf(" Total serial execution time :%s\n", time.Since(start))
}

func abc(x, y int) {
	time.Sleep(time.Second * 1)
	fmt.Printf("x:%d, y:%d\n", x, y)
}

The execution result

[

x:1, y:100
x:1, y:200
x:1, y:300
x:2, y:100
x:2, y:200
x:2, y:300
x:3, y:100
x:3, y:200
x:3, y:300
Total serial execution time :9.0026338s

]

Single coroutine group concurrency

The coroutine group was used to reduce O(n^2) to O(n) The resulting execution time was 3s

//  Single parallel execution 
func SingleConcurrenceRun() {
	start := time.Now()
	xx := []int{1, 2, 3}
	yy := []int{100, 200, 300}
	for _, x := range xx {
		wgg := sync.WaitGroup{}
		for _, y := range yy {
			wgg.Add(1)
			go func(x, y int) {
				defer wgg.Done()
				abc(x, y)
			}(x, y)
		}
		wgg.Wait()
	}
	fmt.Printf(" Total time of single parallel execution :%s\n", time.Since(start))
}
func abc(x, y int) {
	time.Sleep(time.Second * 1)
	fmt.Printf("x:%d, y:%d\n", x, y)
}

The results of

[

x:1, y:300
x:1, y:200
x:1, y:100
x:2, y:100
x:2, y:200
x:2, y:300
x:3, y:300
x:3, y:100
x:3, y:200
Total time of single parallel execution :3.0013813s

]

Nested concurrent execution

Concurrency is performed using nested coroutines. O(n^2) down to O(1) The resulting execution time was 1s

//  Nested execution 
func NestConcurrenceRun() {
	xx := []int{1, 2, 3}
	yy := []int{100, 200, 300}
	start := time.Now()
	wgg := sync.WaitGroup{}
	for _, x := range xx {
		wgg.Add(1)
		go func(x int) {
			wg := sync.WaitGroup{}
			for _, y := range yy {
				wg.Add(1)
				go func(x, y int) {
					defer wg.Done()
					abc(x, y)
				}(x, y)
			}
			wg.Wait()
			wgg.Done()
		}(x)
	}
	wgg.Wait()
	fmt.Printf(" Total nested concurrent execution time :%s\n", time.Since(start))
}
func abc(x, y int) {
	time.Sleep(time.Second * 1)
	fmt.Printf("x:%d, y:%d\n", x, y)
}

The results of

[

x:1, y:200
x:3, y:300
x:3, y:200
x:1, y:300
x:2, y:200
x:1, y:100
x:2, y:300
x:2, y:100
x:3, y:100
Total time of nested concurrent execution :1.0023542s

]

The above is a detailed explanation of Go concurrency, more information about Go concurrency please pay attention to other related articles on this site!


Related articles: