go 编译指示
Tip
- 编译指示一种语言结构,它指示编译器应该如何处理其输入
- go中这样的注释
//go:(注释//与go没有空格) 就是 Go 语言编译指示的实现方式
1 //go:noinline
什么是inline内联优化?
- 函数调用需要将相关寄存器中的数据入栈来保存现场,函数调用完毕又需要弹栈来恢复现场,频繁的这样消耗时间,影响执行效率
- 内联就是将调用的函数直接复制到调用处.这样就不用频繁入栈出栈,减少了开销,执行速度快了.
- 内联的问题
- 增加了代码的重复
- 如果函数被很多很多其他地方调用,都内联优化了,如果本来一个地方被缓存,读取指令快,现在可能缓存没有命中,得重新读取再缓存,慢了
内联优化对比
Tip
//go:noinline顾名思义就是禁止内联优化,通常我们需要调式的时候用- 后面必须跟着 func 的申明
2 //go:linkname
Tip
- 当你想要使用别的包(自己写的包或者go源码的包都行)没有导出(私有)的变量和方法时
//go:linkname localname [importpath.name]- 调试代码时可能会用到这类技术
- 使用go源码中的包
runtime.inheap 这个方法正常情况下我们是没法调用的
package main
import (
// 如果没有使用 也需要import
// _ "unsafe"
"unsafe"
)
// 表示 inheap 的真正实现是 runtime.inheap
//
//go:linkname inheap runtime.inheap
func inheap(arg uintptr) bool // 方法申明,去看 runtime.inheap 复制过来
func main() {
var a int = 1
// false 表示在栈上
println(inheap(uintptr(unsafe.Pointer(&a))))
}- 自己的包中的私有方法