gpt4 book ai didi

go - 为什么 goroutine 这么慢?

转载 作者:IT王子 更新时间:2023-10-29 02:04:08 25 4
gpt4 key购买 nike

我昨天用几乎相同的代码发布了一个问题,询问如何在可变参数函数中实现并发。解决后,我预计该程序在一台发电机上运行的时间与在 30 台以上的发电机上运行的时间几乎相同。好像不是。

我看到的时间是一台发电机,大约 5 毫秒。使用下面的代码,150 毫秒。 (出于某种原因,play.golang 显示为 0)。

为什么会变慢?我的预期是,对于多个 goroutine,它会花费同样长的时间。与启动 goroutines 有关吗?

package main

import (
"fmt"
"sync"
"time"
)

func main() {
t := time.Now()
_ = fanIn(
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
)

fmt.Println(time.Now().Sub(t))
}

func generator(nums ...int) <-chan int {
out := make(chan int, 10)
go func() {
defer close(out)
for _, v := range nums {
out <- v
}
}()
return out
}

func fanIn(in ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int, 10)
wg.Add(len(in))

go func() {
for _, v := range in {
go func(ch <-chan int) {
defer wg.Done()
for val := range ch {
out <- val
}
}(v)
}

}()
go func() {
wg.Wait()
close(out)
}()
return out
}

最佳答案

go rungo build 有一点不同(编译时):
对我来说 17ms(在 2 个内核上)和 3ms(在 8 个内核上),go1.7 amd64:

go rungo build 的区别:
951.0543ms-934.0535ms = 17.0008ms(2 核)
575.3447ms-572.3914ms = 2.9533ms(8 核)

使用 go build 时 8 核和 2 核的区别:
934.0535ms-572.3914ms = 361.6621ms

要获得良好的基准统计数据,请使用大量样本。
尝试更新到最新的 Go 版本(1.7)。

试试这个有效的示例代码,并将您的结果与这些输出进行比较:

package main

import (
"fmt"
"math/rand"
"sync"
"time"
)

func main() {
t := time.Now()
cs := make([]<-chan int, 1000)
for i := 0; i < len(cs); i++ {
cs[i] = generator(rand.Perm(10000)...)
}
ch := fanIn(cs...)
fmt.Println(time.Now().Sub(t))

is := make([]int, 0, len(ch))
for v := range ch {
is = append(is, v)
}
fmt.Println("len=", len(is))
}

func generator(nums ...int) <-chan int {
out := make(chan int, len(nums))
go func() {
defer close(out)
for _, v := range nums {
out <- v
}
}()
return out
}

func fanIn(in ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int, 10)
wg.Add(len(in))

go func() {
for _, v := range in {
go func(ch <-chan int) {
defer wg.Done()
for val := range ch {
out <- val
}
}(v)
}

}()
go func() {
wg.Wait()
close(out)
}()
return out
}

2 核输出(go run):

951.0543ms
len= 10000000

2 核输出(go build):

934.0535ms
len= 10000000

8 核输出(go run):

575.3447ms
len= 10000000

8 核输出(go build):

572.3914ms
len= 10000000

关于go - 为什么 goroutine 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39045307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com