去通道缓冲区长度 - 最佳实践

时间:2018-04-24 15:20:21

标签: go channel

我正在学习Go并且已经开始重新编写我最初用Java编写的测试数据生成程序。我一直对Go的频道/线程可能性感兴趣,因为我编写的许多程序都集中在负载测试系统/记录各种指标上。

在这里,我正在创建一些要写入CSV文件的数据。我开始生成所有数据,然后将其传递给文件。然后我想我会尝试实现一个通道,因此可以在生成数据的同时写入数据。

它有效 - 它几乎消除了首先生成数据和然后编写数据的开销。但是,我发现只有当我的通道有一个足够大的缓冲区来处理生成的所有测试数据时,这才有效:c := make(chan string, count),其中count与我测试数据行的数量相同产生

所以,我的问题是:我经常生成数百万条测试数据记录(负载测试应用程序) - 我应该使用缓冲区大的通道吗?我找不到很多关于缓冲区大小的限制?

以10分钟的计数运行以下内容在~59.5秒内完成;预先生成数据并将其全部写入文件需要大约62秒;使用1 - 100的缓冲区长度需要大约80秒。

const externalRefPrefix = "Ref"
const fileName = "citizens.csv"

var counter int32 = 0

func WriteCitizensForApplication(applicationId string, count int) {
    file, err := os.Create(fileName)

    if err != nil {
        panic(err)
    }

    defer file.Close()

    c := make(chan string, count)

    go generateCitizens(applicationId, count, c)

    for line := range c {
        file.WriteString(line)
    }
}

func generateCitizens(applicationId string, count int, c chan string) {
    for i := 0; i < count; i++ {
        c <- fmt.Sprintf("%v%v\n", applicationId, generateExternalRef())
    }
    close(c)
}

func generateExternalRef() string {
    atomic.AddInt32(&COUNTER, 1)
    return fmt.Sprintf("%v%08d", externalRefPrefix, counter)
}

0 个答案:

没有答案