登录
首页 >  Golang >  Go问答

更快速的替代方案取代不同步的 math/rand

来源:stackoverflow

时间:2024-02-23 19:48:27 436浏览 收藏

哈喽!今天心血来潮给大家带来了《更快速的替代方案取代不同步的 math/rand》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你!

问题内容

我正在尝试优化我的遗传算法。这使用了大量的随机数选择(随机突变等)。

我决定使用 cpu 分析器:

import (
    "runtime/pprof"
)

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {

    if *cpuprofile != "" {
        fmt.Println(*cpuprofile)
        f, err := os.Create(*cpuprofile)
        if err != nil {
            log.Fatal(err)
        }
        _ = pprof.StartCPUProfile(f)
        defer pprof.StopCPUProfile()
    }
    ***app logic***

我很惊讶地发现 cpu 使用率的最大贡献者之一是 sync.(*mutex).unlock,特别是因为我在应用程序中的任何时候都没有使用线程或 goroutine .

一些挖掘发现瓶颈是由同步 math/rand 中的默认源引起的。

有没有一种更快的方法可以使用不同步/阻塞的函数生成随机数?

真正的随机性/准确的伪随机性对于这个应用程序来说并不是那么重要,但如果我没有连续多次获得完全相同的数字,那么它会是首选。


正确答案


正如您所发现的,math/rand 包的默认“随机源”是一个锁定源,适合在并发 goroutine 中使用。您需要使用 NewSource function 为每个 goroutine 创建一个新源,然后使用 New 从中创建一个随机数生成器。来自这个新生成器的伪随机数将与(单个)锁定源以相同的方式工作,除了每个如果从相同的种子开始,生成器将生成自己的相同生成数字的流。

因此,您需要确保提供给 NewSource 的每个种子都是唯一的,以便每个流都是不同的。

如果您正在寻找快速的高质量伪数据-Go 中的随机数,我创建了一个包(我认为,但我显然有偏见)在不牺牲质量的情况下尽可能快地在 Go 中运行(并且与 math/rand 相比显着改进):pgregory.net/rand (benchmarks )。

除了避免任何同步之外,它还使用更快的算法并避免使用 Source 接口来实现内联。

好了,本文到此结束,带大家了解了《更快速的替代方案取代不同步的 math/rand》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>