我尝试/尝试了三种反转字符串的方法,使用 Runes 和就地交换。建议像这里这样的多个地方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.Builderfunc 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()}使用从输入字符串末尾填充的字节数组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)}我想ReverseWithRune,ReverseWithBuilder应该比.快ReverseWithByteArray。ReverseWithByteArray无复制、更少的分配等。但对于小的 9 或大的 99999 长度字符串,字节数组的基准测试总是更快。RuneArr_9-4 9545110 111.3 ns/op 16 B/op 1 allocs/opStringBuil_9-4 24685213 40.79 ns/op 16 B/op 1 allocs/opByteArr_9-4 23045233 52.35 ns/op 32 B/op 2 allocs/opRune_99999-4 1110 1002334 ns/op 507904 B/op 2 allocs/opStringBuil_99999-4 6679 179333 ns/op 106496 B/op 1 allocs/opByteArr_99999-4 12200 97876 ns/op 212992 B/op 2 allocs/op我的问题是为什么 rune 和 builder 方法没有更快,尽管迭代次数较少(lenght/2)和到位等。另一个明显的问题是,符文/生成器方法可以改进吗?可能是我在这里用错了。细节goos: linux goarch: amd64 cpu: Intel(R) Core(TM) i5-7200U CPU @2.50GHz go version: go1.19.2 linux/amd64我试图查看配置文件,它显示了slicerunetostring主要strings.Builder.WriteBytes的繁重操作。 字节反向也很大,但也是因为它有更多的操作。
1 回答
大话西游666
TA贡献1817条经验 获得超14个赞
哪个更快并不那么重要,因为三分之二是不正确的。只有ReverseWithRune是正确的。
其他人操纵字符串中的各个字节。在 Go 中,字符串是 UTF-8 编码的,这是一种多字节编码。代码点超出 ASCII 范围的字符使用超过 1 个字节进行编码,如果逐字节反转它们,则会破坏该字符,因为反向多字节编码与正向编码并不相同。
您可以在 Go playground 上轻松检查它,使用"Hello, 世界"其标准示例中提供的字符串:
https://go.dev/play/p/oYfPsO-C_OR
输出:
ReverseWithByteArray ��疸� ,olleH
ReverseWithBuilder ��疸� ,olleH
ReverseWithRune 界世 ,olleH
至于为什么比较慢:它涉及创建一个(32 位整数)ReverseWithRune切片,然后将字符串复制到其中,同时从 UTF-8 编码解码字符边界。rune然后你反转它,然后分配一个新的字节数组,然后将一个切片编码rune为UTF-8。
- 1 回答
- 0 关注
- 55 浏览
添加回答
举报
0/150
提交
取消