我有一个工作正常的记录器,但在内存分配方面会产生相当多的开销。下面的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{}) {}
- 1 回答
- 0 关注
- 102 浏览
添加回答
举报
0/150
提交
取消