gpt4 book ai didi

go - ...interface{} 函数参数中的 "Dereference"个元素

转载 作者:数据小太阳 更新时间:2023-10-29 03:34:02 24 4
gpt4 key购买 nike

我有一个工作正常的记录器,但在内存分配方面产生了相当多的开销。下面的 Debug() 函数不是故意打印的,因为 logOutputLevel 不够高。

var logOutputLevel = 2
func 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/op
BenchmarkLogRef-8 500000000 3.17 ns/op 0 B/op 0 allocs/op

现在一切都很好,我正在尝试重新设计 Debug() 方法以仅接受一个字符串和无限指针参数。稍后,如果日志级别足够高,我想“取消引用”所有参数并将它们传递给 fmt.Printf()

我怎样才能做到这一点? “仅指针”是否有特定的语言习语?我假设 ...*interface{} 表示指向 interface{} 的指针(并且任何值都不应是指针)。

最佳答案

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

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

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

这是大多数日志包处理它的方式。查看glog Verbose type例如。

您可以使用构建标签有条件地编译 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{}) {}

关于go - ...interface{} 函数参数中的 "Dereference"个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54616883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com