首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串反向使用[]rune和strings.Builder比字节数组慢

字符串反向使用[]rune和strings.Builder比字节数组慢
EN

Stack Overflow用户
提问于 2022-11-19 06:07:06
回答 1查看 38关注 0票数 -3

我尝试了三种逆转字符串的方法,使用了Runes和就位交换。建议像here这样的多个地方

代码语言:javascript
复制
func ReverseWithRune(str string) string {
    runes := []rune(str)
    for i, j := len(runes)-1, 0; j < i; i, j = i-1, j+1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

用strings.Builder

代码语言:javascript
复制
func ReverseWithBuilder(str string) string {
    var ret strings.Builder
    strLen := len(str)
    ret.Grow(strLen)
    for i := strLen - 1; i >= 0; i-- {
        ret.WriteByte(str[i])
    }
    return ret.String()
}

从输入字符串的末尾填充字节数组。

代码语言:javascript
复制
func ReverseWithByteArray(str string) string {
    strLen := len(str)
    ret := make([]byte, strLen)
    for i := strLen - 1; i >= 0; i-- {
        ret[strLen-i-1] = str[i]
    }
    return string(ret)
}

我认为ReverseWithRuneReverseWithBuilder应该比ReverseWithByteArray快。没有复制,分配较少等等,但是对于小9或大99999长的字符串(字节数组),基准测试的速度总是更快。

代码语言:javascript
复制
RuneArr_9-4           9545110       111.3 ns/op       16 B/op        1 allocs/op
StringBuil_9-4       24685213       40.79 ns/op       16 B/op        1 allocs/op
ByteArr_9-4          23045233       52.35 ns/op       32 B/op        2 allocs/op

Rune_99999-4             1110     1002334 ns/op   507904 B/op        2 allocs/op
StringBuil_99999-4       6679      179333 ns/op   106496 B/op        1 allocs/op
ByteArr_99999-4         12200       97876 ns/op   212992 B/op        2 allocs/op

我的问题是

  1. 为什么符文和构建器的方法不能更快,尽管迭代次数较少(lenght/2)和位置等等。
  2. 显然是另一个,可以改进符文/构建器的应用程序吗?也许我在这里用错了它们。--

详细信息

代码语言:javascript
复制
goos: linux goarch: amd64 
cpu: Intel(R) Core(TM) i5-7200U CPU @2.50GHz 
go version: go1.19.2 linux/amd64

我试着查看profile,它向slicerunetostringstrings.Builder.WriteBytes展示了主要的繁重操作。

字节反向也很大,但也是因为它有更多的操作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-19 06:59:51

哪一个更快并不重要,因为每三个人中就有两个是不正确的。只有ReverseWithRune是正确的。

其他的操作字符串中的单个字节。在Go中,字符串是UTF-8编码的,这是一种多字节编码.在ASCII范围外有一个编码点的字符使用超过1个字节进行编码,如果您逐字节对它们进行反向编码,则会打破该字符,因为反向多字节编码并不意味着与正向编码相同。

您可以在Go操场上轻松地检查它,使用标准示例中提供的字符串"Hello, 世界"

https://go.dev/play/p/oYfPsO-C_OR

输出:

代码语言:javascript
复制
ReverseWithByteArray ��疸� ,olleH
ReverseWithBuilder ��疸� ,olleH
ReverseWithRune 界世 ,olleH

至于为什么ReverseWithRune速度慢:它涉及创建rune的一个片段(32位整数),然后将字符串复制到其中,同时从UTF-8编码中解码字符边界。然后将其反转,然后分配一个新的字节数组,然后将rune的一个片段编码为UTF-8。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74497900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档