本书未发布

Go 性能优化细节

未匹配的标注
  1. 函数调用
    C 函数调用,参数6个之内用的是寄存器,大于6个则会用栈存储多余的参数。返回只能有一个,因为返回值也是用的一个寄存器。
    Go 函数调用,参数都放在栈存储。返回值也支持多个。

  2. interface{} 和 interface 区别

  • interface{} 和C语言的 *void 不同,不能代表任意类型。举个例子:
  • interface{} 不带方法(空接口);interface带方法。
  • 类型断言:运行时类型判断,快速通过结构体内的hash。
  • 动态派发(类型转换):在运行期间选择具体多态操作(方法或者函数)执行的过程,它是面向对象语言中的常见特性。调用接口类型的方法时,如果编译期间不能确认接口的类型,Go 语言会在运行期间决定具体调用该方法的哪个实现。
  • 结构体调用:
  • 指针式调用:比结构体调用性能更优。原因是动态派发在结构体上的表现非常差。
直接调用 动态派发
指针 ~3.03ns
结构体 ~3.09ns
type TestStruct struct{}
func NilOrNot(v interface{}) bool {
    return v == nil
}
func main() {
    var s *TestStruct
    fmt.Println(s == nil)      // #=> true
    fmt.Println(NilOrNot(s))   // #=> false
}

interface{} 的底层数据结构是 eface.

type eface struct {
    _type *_type
    data  unsafe.Pointer
}
type _type struct {
    size       uintptr
    ptrdata    uintptr
    hash       uint32
    tflag      tflag
    align      uint8
    fieldAlign uint8
    kind       uint8
    equal      func(unsafe.Pointer, unsafe.Pointer) bool
    gcdata     *byte
    str        nameOff
    ptrToThis  typeOff
}

interface的底层数据结构 iface

type iface struct { // 16 字节
    tab  *itab
    data unsafe.Pointer
}
type itab struct { // 32 字节
    inter *interfacetype
    _type *_type
    hash  uint32
    _     [4]byte
    fun   [1]uintptr
}

defer 性能优化

堆上分配 < 栈上分配 < 开放编码

With normal (stack-allocated) defers only:         35.4  ns/op
With open-coded defers:                             5.6  ns/op
Cost of function call alone (remove defer keyword): 4.4  ns/op
  1. 函数的 defer 数量少于或者等于 8 个;
  2. 函数的 defer 关键字不能在循环中执行;
  3. 函数的 return 语句与 defer 语句的乘积小于或者等于 15 个;

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~