【发布时间】:2015-11-09 19:38:57
【问题描述】:
我有一个非常简单的脚本,它发出一个 get 请求,然后对响应做一些事情。我有 2 个版本,一个使用 go 例程,一个没有我对两者进行基准测试,速度没有差异。这是我正在做的一个愚蠢的版本:
普通版:
func main() {
url := "http://finance.yahoo.com/q?s=aapl"
for i := 0; i < 250; i++ {
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
fmt.Println(resp.Status)
}
}
去常规:
func main() {
url := "http://finance.yahoo.com/q?s=aapl"
for i := 0; i < 250; i++ {
wg.Add(1)
go run(url, &wg)
wg.Wait()
}
}
func run(url string, wg *sync.WaitGroup) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
fmt.Println(resp.Status)
}
在大多数情况下,当我使用 go 例程时,程序的执行时间会更长。为了有效地使用并发,我缺少什么概念?
【问题讨论】:
-
我相信因为你在循环中有
wg.Wait(),它会阻塞在那里,直到run在你的“并发”示例中返回含义,它应该表现更差,因为你'添加了等待守卫和 goroutine 开销。我相信这行代码需要是 main 的底部,所以你阻塞直到所有 go 例程完成,而不是在每个例程完成。 -
另外,你的例子很糟糕,因为你实际上并没有做任何工作。如果这更完整并包括响应处理,那么随着并发请求数量的增加,您可能会看到性能上的重大差异。由于这里唯一真正需要时间的是请求/响应实际上是通过网络传输的,因此不太可能一开始就很好地展示这个概念。
-
@evanmcdonnal gotcha 是的,我简化了这个例子,只是为了展示我是如何调用 go 例程的。我知道 http 也是一个糟糕的基准,因为它有可能导致执行时间变慢的外部因素。更重要的是,我是否正确地调用了您指出的例程,而我不是。谢谢!
标签: go concurrency goroutine