为什么 Goroutines 花费的时间与顺序执行几乎相同?

Why does the Goroutines take almost identical time as sequential execution?

我正在调用两个函数,每个函数都带有 Go 例程,我希望同时执行它们所花费的时间应该比我 运行 它们一个时少得多一次。但我看到的恰恰相反,它需要相同或有时 更少 的时间来并行 运行 它们。

协程

    start := time.Now()
    incomeChan := make(chan func() ([]models.Cashflow, *models.ErrorResponse))
    expenseChan := make(chan func() ([]models.Cashflow, *models.ErrorResponse))

    go func(from, to string, cr *fa.Client, c chan<-func() ([]models.Cashflow, *models.ErrorResponse)) {
        log.Println("fetching income")
        c <- func() ([]models.Cashflow, *models.ErrorResponse) { return incomes(from, to, cr)}
        close(c)
    }(from, to, cr, incomeChan)

    go func(from, to string, cr *fa.Client, c chan<-func() ([]models.Cashflow, *models.ErrorResponse)){
        log.Println("fetching expenses")
        c <- func() ([]models.Cashflow, *models.ErrorResponse) {return expenses(from, to, cr)}
        close(c)
    } (from, to, cr, expenseChan)

    income, inErr := (<- incomeChan)()
    if inErr != nil {
        log.Printf("%#v", inErr)
        w.WriteHeader(inErr.Code)
        fmt.Fprint(w, helper.JsonStringify(inErr))
        return
    }
    log.Println("income fetch completed")

    expense, exErr := (<- expenseChan)()
    if exErr != nil {
        log.Printf("%#v", exErr)
        w.WriteHeader(exErr.Code)
        fmt.Fprint(w, helper.JsonStringify(exErr))
        return
    }
    log.Println("expense fetch completed")
    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())

输出

3.33s elapsed
2.79s elapsed
3.37s elapsed

顺序

    income, inErr := incomes(from, to, cr)
    if inErr != nil {
        log.Printf("%#v", inErr)
        w.WriteHeader(inErr.Code)
        fmt.Fprint(w, helper.JsonStringify(inErr))
        return
    }
    
    expense, exErr := expenses(from, to, cr)
    if exErr != nil {
        log.Printf("%#v", exErr)
        w.WriteHeader(exErr.Code)
        fmt.Fprint(w, helper.JsonStringify(exErr))
        return
    }

    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())

输出

2.98s elapsed
3.03s elapsed
2.70s elapsed

是我做错了吗?我原以为它会花更少的时间在 Goroutine 上。

如果有人知道我在这里可能做错了什么或有任何建议,非常感谢。

首先,您混淆了并行性和并发性。 Goroutines 处理并发性,而不是并行性。有关差异的更多背​​景信息,Go 的创建者之一有一个名为 Concurrency is not Parallelism.

的演讲

现在进入实际答案。

你的 goroutines 实际上并不处理任何一个函数的处理,而是发送一个调用 expensesincomes 的函数,然后你依次调用它们。这意味着在您调用 income, inErr := (<- incomeChan)().

之前不会计算 incomes() 的实际结果

本质上,您的“Goroutines”示例在功能上与您的“顺序”示例相同,但是 goroutine 带来了额外的开销,因为它们不能保证立即安排。