为什么并发代码需要更多时间来执行

我有一个名为 linearize 的函数……我试图加快它的执行速度,但惊讶地发现它变得更慢了。我是否错过了什么或搞砸了基本面..


根据我的理解,事情应该有所改善..


谢谢,


package main


import (

    "fmt"

    "math"

    "sync"

    "time"

)


var rgb []float64


func linearizeWithWg(v float64, idx int, wg *sync.WaitGroup) {

    defer wg.Done()


    if v <= 0.04045 {

        rgb[idx] = v / 12.92

    } else {

        rgb[idx] = math.Pow((v+0.055)/1.055, 2.4)

    }

}


func linearizeWithGoR(v float64) float64 {

    res := make(chan float64)


    go func(input float64) {

        if input <= 0.04045 {

            res <- input / 12.92

        } else {

            res <- math.Pow((input+0.055)/1.055, 2.4)

        }

    }(v)

    return <-res

}


func linearizeNomal(v float64) float64 {

    if v <= 0.04045 {

        return v / 12.92

    }

    return math.Pow((v+0.055)/1.055, 2.4)

}


func main() {

    start := time.Now()

    const C = 1.0 / 255.0


    //Normal Execution

    for i := 0; i < 100000; i++ {

        linearizeNomal(float64(i) * C * 0.5)

        linearizeNomal(float64(i) * C * 1.5)

        linearizeNomal(float64(i) * C * 4.5)

    }

    elaspsed := time.Since(start)

    fmt.Println(elaspsed)


    //With GoRoutines.. Slow

    start = time.Now()

    for i := 0; i < 100000; i++ {

        linearizeWithGoR(float64(i) * C * 0.5)

        linearizeWithGoR(float64(i) * C * 1.5)

        linearizeWithGoR(float64(i) * C * 2.5)

    }

    elaspsed = time.Since(start)

    fmt.Println(elaspsed)


    //With WaitGroup. Slow


    for i := 0; i < 100000; i++ {

        rgb = make([]float64, 3)

        var wg sync.WaitGroup

        wg.Add(3)

        linearizeWithWg(float64(i)*C*0.5, 0, &wg)

        linearizeWithWg(float64(i)*C*1.5, 1, &wg)

        linearizeWithWg(float64(i)*C*4.5, 2, &wg)

        wg.Wait()

    }

    elaspsed = time.Since(start)

    fmt.Println(elaspsed)


}


慕后森
浏览 190回答 2
2回答

拉莫斯之舞

所有与并发相关的函数(通道创建、通道发送、goroutine 创建)的开销远远大于您在每个 goroutine 中执行的两条指令。此外,您的 goroutine 版本基本上是串行的,因为您生成了一个 goroutine 并立即等待其通道的结果。等待组版本类似。使用少量 goroutine 再试一次,每个 goroutine 执行一个循环块。@Joker_vD 也有一个很好的观点,可以确保它GOMAXPROCS大于 1。

GCT1015

你的问题是你实际上并没有同时做任何事情。在工作组示例中,您需要调用&nbsp;go linearizeWithWg(...)在 goroutine 示例中,您启动了一个 goroutine,然后等待它在函数中结束。要同时运行它,您需要一个缓冲的响应通道,并让另一个 goroutine 获取响应
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go