我有一個工作正常的記錄器,但在內存分配方面會產生相當多的開銷。下面的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 關注
- 134 瀏覽
添加回答
舉報
0/150
提交
取消