You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中是否存在快速唯一标识函数调用方的实现方案?

解决方案

该需求完全可以通过Go原生能力实现,无需每次调用日志都承担runtime.Caller()的完整开销,有以下几种可行方案:

方案1:使用runtime.GetCallerPC()(推荐,Go 1.18及以上支持)

runtime.GetCallerPC(skip int)是Go 1.18新增的接口,仅返回调用方的程序计数器(PC),不会执行解析文件名、行号的额外操作,单次调用耗时仅30~50ns,远低于runtime.Caller()的500ns开销。你可以将PC作为缓存key,仅在第一次命中缓存失败时调用runtime.Caller()获取文件、行号信息存入缓存即可:

package main

import (
	"fmt"
	"runtime"
	"sync"
)

type Info struct {
	file string
	line int
	// otherData
}

// 用sync.Map保证并发安全,也可以用sync.RWMutex+普通map
var infoMap sync.Map

func Log(str string, args ...interface{}) {
	pc := runtime.GetCallerPC(1)
	infoVal, found := infoMap.Load(pc)
	if !found {
		_, file, line, _ := runtime.Caller(1)
		info := Info{file: file, line: line}
		// 其他自定义数据生成逻辑写在这里
		infoMap.Store(pc, info)
		infoVal = info
	}
	info := infoVal.(Info)
	fmt.Println(info.file, info.line, fmt.Sprintf(str, args...))
}

// client code
func foo() {
	// do some work
	Log("Here's a message with <> some <> args", "foo", "bar")
	// do more work
	Log("The cow jumped over the moon")
}

func main() {
	foo()
	foo()
}

该方案完全兼容你现有的调用方式,无需修改业务侧代码,性能提升明显。

方案2:低版本Go兼容方案

如果你的Go版本低于1.18,可以用runtime.Callers()仅提取PC,性能也远高于runtime.Caller():

func getCallerPC(skip int) uintptr {
	var pcs [1]uintptr
	// skip层数需要加上当前getCallerPC本身的一层
	runtime.Callers(skip+1, pcs[:])
	return pcs[0]
}

将Log函数中获取PC的逻辑替换为调用getCallerPC(1)即可,其余逻辑和方案1一致。

方案3:极致性能优化方案

如果需要完全消除运行期的PC获取开销,可以在调用侧预初始化日志实例,每个日志点仅初始化一次:

func NewLogger() func(string, ...interface{}) {
	pc := runtime.GetCallerPC(1)
	_, file, line, _ := runtime.Caller(1)
	info := Info{file: file, line: line}
	// 其他自定义数据生成逻辑
	return func(str string, args ...interface{}) {
		fmt.Println(info.file, info.line, fmt.Sprintf(str, args...))
	}
}

// 业务侧使用
func foo() {
	log1 := NewLogger() // 仅第一次调用时执行runtime操作
	log1("第一条日志")
	log2 := NewLogger()
	log2("第二条日志")
}

该方案每次日志调用完全没有runtime相关开销,性能最高,仅需要业务侧做少量调整。

内容的提问来源于stack exchange,提问作者Locke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:36:05