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

在切片上调用 len() 有多快?

在切片上调用 len() 有多快?

Go
MMMHUHU 2023-07-26 16:35:03
我想知道访问len()切片的速度有多快。如果我需要多次使用切片的长度,是否值得将其存储到变量中int?或者调用len()会像访问 int 变量一样进行优化?(在这种情况下,用户无需存储变量的长度。)谢谢。
查看完整描述

2 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

这是我的理解:

你可以看作slicestruct其中的length一员。

函数所做的唯一事情len()就是读取 的该成员type slice struct,因此无需担心其性能——它与读取您length int自己创建的成员一样快。


查看完整回答
反对 回复 2023-07-26
?
青春有我

TA贡献1784条经验 获得超8个赞

所有内置函数实际上都不起作用。它可能是一堆其他函数或只是一个 asm 指令(就本例而言)。


这是切片结构:


type SliceHeader struct {

    Data uintptr // sizeof(uintptr) = 8 byte

    Len  int

    Cap  int

}

要获取切片的 len,我们应该获取切片指针的偏移量。Go 惯用变体如下所示:


*(*int)(unsafe.Pointer(uintptr(pointer_to_slice) + 8))

可以看到,len(b)的输出goasm代码等于一条指令: https://godbolt.org/z/z0PtMe


var b1 = []byte{1, 2, 3}

var b2 = []byte{4, 5, 6}


func main() {

   l1 := len(b1)


   if len(b2) == l1 {

       println(l1)

   } else {

       println(len(b2))

   }

}

l1 := len(b1)


=


movq    "".b1+8(SB), AX // ax == l1


但是,对于len(b2) == l1编译器创建附加变量:


movq    "".b2+8(SB), CX // cx == len(b2) in "if" statement


因此,我们可以得出结论,为长度创建新变量不会影响性能。


查看完整回答
反对 回复 2023-07-26
  • 2 回答
  • 0 关注
  • 93 浏览
慕课专栏
更多

添加回答

举报

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