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

...interface{} 函数参数中的“取消引用”元素

...interface{} 函数参数中的“取消引用”元素

Go
长风秋雁 2023-06-05 18:18:57
我有一个工作正常的记录器,但在内存分配方面会产生相当多的开销。下面的Debug()函数不是故意打印的,因为logOutputLevel不够高。var logOutputLevel = 2func Debug(s string, args ...interface{}) {    if logOutputLevel > 1 { return }    fmt.Printf(s, args...)}在向它传递值时,该方法仍然会产生相当多的分配。将指针传递给它时,它不会产生大量分配。请参阅以下基准:func BenchmarkLog(b *testing.B) {    x := "abc"    for n := 0; n < b.N; n++ {        Debug("test %s", x)    }}func BenchmarkLogRef(b *testing.B) {    x := "abc"    for n := 0; n < b.N; n++ {        Debug("test %s", &x)    }}生产:BenchmarkLog-8          50000000            43.1 ns/op        16 B/op          1 allocs/opBenchmarkLogRef-8       500000000            3.17 ns/op        0 B/op          0 allocs/op现在一切都很好,我正在尝试重新设计该Debug()方法以仅接受一个字符串和无限指针参数。稍后,fmt.Printf()如果日志级别足够高,我想“取消引用”所有参数并将它们传递给。我怎样才能做到这一点?“仅指针”是否有特定的语言习语?我假设这...*interface{}意味着指向 an 的指针interface{}(而不是任何值都应该是指针)。
查看完整描述

1 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

阻止分配的唯一方法是首先不进行分配。

这通常是通过在评估之前将调试语句放在条件块中来完成的:

if logOutputLevel > 1 {
    Debug("test: %s", x)
}

这是大多数日志记录包处理它的方式。

您可以使用构建标签有条件地编译Debug函数,并完全忽略参数。语言规范不能保证不分配,但如果当前性能可以接受,编译器将来可能会进行优化。Debug使用两个单独的文件,您可以在编译时在实现之间切换:

调试.go

// +build debug


package main


import "log"


func Debug(fmt string, args ...interface{}) {

    log.Printf(fmt, args...)

}

发布.go


// +build !debug


package main


func Debug(_ string, _ ...interface{}) {}


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

添加回答

举报

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