为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
三国纷争 2023-06-05 16:57:37
当我有字符串&ldquo;hogemogehogemogehogemoge 世界世界&rdquo;时,哪个代码更适合避免内存分配以获得最后一个符文?关于获取 Golang String 的最后一个 X 字符也有类似的问题。如何获取 Golang 字符串的最后 X 个字符?如果我只想获得最后一个符文,而不需要任何额外的操作,我想确定哪个是首选。package mainimport (    "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)}
查看完整描述

1 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

当性能和分配成为问题时,您应该运行基准测试。


首先让我们修改您的函数以不打印而是返回结果:


func getLastRune(s string, c int) string {

    j := len(s)

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

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

        j -= size

    }

    return s[j:]

}


func getLastRune2(s string, c int) string {

    r := []rune(s)

    if c > len(r) {

        c = len(r)

    }

    return string(r[len(r)-c:])

}

基准函数:


var s = "hogemogehogemogehogemoge世界世界世界a"


func BenchmarkGetLastRune(b *testing.B) {

    for i := 0; i < b.N; i++ {

        getLastRune(s, 3)

    }

}


func BenchmarkGetLastRune2(b *testing.B) {

    for i := 0; i < b.N; i++ {

        getLastRune2(s, 3)

    }

}

运行它们:


go test -bench . -benchmem

结果:


BenchmarkGetLastRune-4     30000000     36.9 ns/op     0 B/op    0 allocs/op

BenchmarkGetLastRune2-4    10000000    165 ns/op       0 B/op    0 allocs/op

getLastRune()快了 4 倍多。它们都没有进行任何分配,但这是由于编译器优化(将 a 转换string为[]rune和返回通常需要分配)。


如果我们在禁用优化的情况下运行基准测试:


go test -gcflags '-N -l' -bench . -benchmem

结果:


BenchmarkGetLastRune-4     30000000    46.2 ns/op      0 B/op    0 allocs/op

BenchmarkGetLastRune2-4    10000000   197 ns/op       16 B/op    1 allocs/op

编译器优化与否,getLastRune()是明显的赢家。


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 170 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信