昨天我用几乎相同的代码发布了一个问题,询问如何在可变函数之间同时进行。解决之后,我希望该程序使用一台生成器运行与运行30+几乎相同的时间。似乎并非如此。
我看到的时间是一台发电机,大约5毫秒。与下面的代码是150ms。(由于某种原因,play.golang显示为0)。
为什么慢呢?我的期望是,使用多个goroutine,大约需要很长时间。与旋转goroutine有关吗?
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 run
和go build
(编译时间)之间有一点区别:
对我来说17ms
(在2个内核上)和3ms
(在8个内核上)具有go1.7 amd64
:
go run
和之间的差go build
:
951.0543ms-934.0535ms = 17.0008ms(2核)
575.3447ms-572.3914ms = 2.9533ms(8核)
8核与2核之间的差为go build
:
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核(with go run
):
575.3447ms
len= 10000000
输出8核(with go build
):
572.3914ms
len= 10000000
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句