哪个更好地获取 Golang 字符串的最后一个 X 字符?

当我有字符串“hogemogehogemogehogemoge 世界世界”时,哪个代码更适合避免内存分配以获得最后一个符文?

关于获取 Golang String 的最后一个 X 字符也有类似的问题。

如何获取 Golang 字符串的最后 X 个字符?

如果我只想获得最后一个符文,而不需要任何额外的操作,我想确定哪个是首选。

package main


import (

    "fmt"

    "unicode/utf8"

)


func main() {

    // which is more better for memory allocation?

    s := "hogemogehogemogehogemoge世界世界世界a"

    getLastRune(s, 3)

    getLastRune2(s, 3)

}


func getLastRune(s string, c int) {

    // DecodeLastRuneInString

    j := len(s)

    for i := 0; i < c && j > 0; i++ {

        _, size := utf8.DecodeLastRuneInString(s[:j])

        j -= size

    }

    lastByRune := s[j:]

    fmt.Println(lastByRune)

}


func getLastRune2(s string, c int) {

    // string -> []rune

    r := []rune(s)

    lastByRune := string(r[len(r)-c:])

    fmt.Println(lastByRune)

}

三国纷争
浏览 270回答 1
1回答

米琪卡哇伊

当性能和分配成为问题时,您应该运行基准测试。首先让我们修改您的函数以不打印而是返回结果:func getLastRune(s string, c int) string {&nbsp; &nbsp; j := len(s)&nbsp; &nbsp; for i := 0; i < c && j > 0; i++ {&nbsp; &nbsp; &nbsp; &nbsp; _, size := utf8.DecodeLastRuneInString(s[:j])&nbsp; &nbsp; &nbsp; &nbsp; j -= size&nbsp; &nbsp; }&nbsp; &nbsp; return s[j:]}func getLastRune2(s string, c int) string {&nbsp; &nbsp; r := []rune(s)&nbsp; &nbsp; if c > len(r) {&nbsp; &nbsp; &nbsp; &nbsp; c = len(r)&nbsp; &nbsp; }&nbsp; &nbsp; return string(r[len(r)-c:])}基准函数:var s = "hogemogehogemogehogemoge世界世界世界a"func BenchmarkGetLastRune(b *testing.B) {&nbsp; &nbsp; for i := 0; i < b.N; i++ {&nbsp; &nbsp; &nbsp; &nbsp; getLastRune(s, 3)&nbsp; &nbsp; }}func BenchmarkGetLastRune2(b *testing.B) {&nbsp; &nbsp; for i := 0; i < b.N; i++ {&nbsp; &nbsp; &nbsp; &nbsp; getLastRune2(s, 3)&nbsp; &nbsp; }}运行它们:go test -bench . -benchmem结果:BenchmarkGetLastRune-4&nbsp; &nbsp; &nbsp;30000000&nbsp; &nbsp; &nbsp;36.9 ns/op&nbsp; &nbsp; &nbsp;0 B/op&nbsp; &nbsp; 0 allocs/opBenchmarkGetLastRune2-4&nbsp; &nbsp; 10000000&nbsp; &nbsp; 165 ns/op&nbsp; &nbsp; &nbsp; &nbsp;0 B/op&nbsp; &nbsp; 0 allocs/opgetLastRune()快了 4 倍多。它们都没有进行任何分配,但这是由于编译器优化(将 a 转换string为[]rune和返回通常需要分配)。如果我们在禁用优化的情况下运行基准测试:go test -gcflags '-N -l' -bench . -benchmem结果:BenchmarkGetLastRune-4&nbsp; &nbsp; &nbsp;30000000&nbsp; &nbsp; 46.2 ns/op&nbsp; &nbsp; &nbsp; 0 B/op&nbsp; &nbsp; 0 allocs/opBenchmarkGetLastRune2-4&nbsp; &nbsp; 10000000&nbsp; &nbsp;197 ns/op&nbsp; &nbsp; &nbsp; &nbsp;16 B/op&nbsp; &nbsp; 1 allocs/op编译器优化与否,getLastRune()是明显的赢家。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go