我嘗試/嘗試了三種反轉(zhuǎn)字符串的方法,使用 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()}使用從輸入字符串末尾填充的字節(jié)數(shù)組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應(yīng)該比.快ReverseWithByteArray。ReverseWithByteArray無復(fù)制、更少的分配等。但對于小的 9 或大的 99999 長度字符串,字節(jié)數(shù)組的基準(zhǔn)測試總是更快。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 方法沒有更快,盡管迭代次數(shù)較少(lenght/2)和到位等。另一個明顯的問題是,符文/生成器方法可以改進嗎?可能是我在這里用錯了。細節(jié)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的繁重操作。 字節(jié)反向也很大,但也是因為它有更多的操作。
1 回答

大話西游666
TA貢獻1817條經(jīng)驗 獲得超14個贊
哪個更快并不那么重要,因為三分之二是不正確的。只有ReverseWithRune是正確的。
其他人操縱字符串中的各個字節(jié)。在 Go 中,字符串是 UTF-8 編碼的,這是一種多字節(jié)編碼。代碼點超出 ASCII 范圍的字符使用超過 1 個字節(jié)進行編碼,如果逐字節(jié)反轉(zhuǎn)它們,則會破壞該字符,因為反向多字節(jié)編碼與正向編碼并不相同。
您可以在 Go playground 上輕松檢查它,使用"Hello, 世界"其標(biāo)準(zhǔn)示例中提供的字符串:
https://go.dev/play/p/oYfPsO-C_OR
輸出:
ReverseWithByteArray ??疸? ,olleH
ReverseWithBuilder ??疸? ,olleH
ReverseWithRune 界世 ,olleH
至于為什么比較慢:它涉及創(chuàng)建一個(32 位整數(shù))ReverseWithRune切片,然后將字符串復(fù)制到其中,同時從 UTF-8 編碼解碼字符邊界。rune然后你反轉(zhuǎn)它,然后分配一個新的字節(jié)數(shù)組,然后將一個切片編碼rune為UTF-8。
- 1 回答
- 0 關(guān)注
- 84 瀏覽
添加回答
舉報
0/150
提交
取消