栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Go中生成长随机字符串的最快方法是什么?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Go中生成长随机字符串的最快方法是什么?

这在我的盒子上大约有200MBps。有明显的改进空间。

type randomDataMaker struct {    src rand.Source}func (r *randomDataMaker) Read(p []byte) (n int, err error) {    for i := range p {        p[i] = byte(r.src.Int63() & 0xff)    }    return len(p), nil}

您只

io.CopyN
需要生成所需的字符串即可。显然,您可以在途中或其他情况下调整字符集。

这个模型的好处是,它只是一个,

io.Reader
因此您可以使用它制作任何东西。

测试如下:

func BenchmarkRandomDataMaker(b *testing.B) {    randomSrc := randomDataMaker{rand.NewSource(1028890720402726901)}    for i := 0; i < b.N; i++ {        b.SetBytes(int64(i))        _, err := io.CopyN(ioutil.Discard, &randomSrc, int64(i))        if err != nil { b.Fatalf("Error copying at %v: %v", i, err)        }    }}

在我的2.2GHz i7的一个核心上:

BenchmarkRandomDataMaker       50000        246512 ns/op     202.83 MB/s

编辑

自从编写基准测试以来,我认为我会做一些明显的改进(减少对随机性的呼唤)。使用rand的1/8调用,它的运行速度快了大约4倍,尽管这是一个很大的丑陋之处:

新版本:

func (r *randomDataMaker) Read(p []byte) (n int, err error) {    todo := len(p)    offset := 0    for {        val := int64(r.src.Int63())        for i := 0; i < 8; i++ { p[offset] = byte(val & 0xff) todo-- if todo == 0 {     return len(p), nil } offset++ val >>= 8        }    }    panic("unreachable")}

新基准:

BenchmarkRandomDataMaker      200000        251148 ns/op     796.34 MB/s

编辑2

因为它是多余的,所以在强制转换为字节时使用了掩码。更快地得到了很多:

BenchmarkRandomDataMaker      200000        231843 ns/op     862.64 MB/s

(这是这么多比真正的工作更容易 叹息

编辑3

这是今天在irc中提出的,所以我发布了一个库。另外,我的实际基准测试工具虽然对相对速度有用,但其报告不够准确。

我创建了randbo,您可以在需要它们的地方重复使用它们以产生随机流。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/448132.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号