【发布时间】:2019-09-10 13:46:00
【问题描述】:
我有一个 HTTP 处理程序,它有 40 个设置为 os.Stdout 的记录器。
它对我来说很好,因为我是目前唯一的测试者。 但是,到了制作的时候,恐怕开销太大了。
当前记录器设置为 os.Stdout 和 os.Stderr。 但一旦进入生产阶段,os.Stdout 将设置为 ioutil.discard。
第一季度。如果我仍然设置要丢弃的记录器,它会影响性能吗?
第二季度。对于最佳实践,从 HTTP 处理程序中完全删除记录器会更好吗?
---- 更新----
package main
import (
"time"
"fmt"
"log"
"io/ioutil"
"io"
)
func testPrintf(w io.Writer, note string, cnt int) {
l := log.New(w, "", 0)
t1 := time.Now()
for i:=0; i<cnt; i++ {
l.Printf("%s - %d", "test", i)
}
t2 := time.Now()
fmt.Printf("%-15s %-15s, %v\n","Printf ", note, t2.Sub(t1))
}
func testPrintln(w io.Writer, note string, cnt int) {
l := log.New(w, "", 0)
t1 := time.Now()
for i:=0; i<cnt; i++ {
l.Println("test" + string(i))
}
t2 := time.Now()
fmt.Printf("%-15s %-15s, %v\n","Println", note, t2.Sub(t1))
}
func testDoNothing(w io.Writer, note string, cnt int) {
//l := log.New(w, "", 0)
t1 := time.Now()
for i:=0; i<cnt; i++ {
_ = "test" + string(i) // evaluated but didn't do any.
}
t2 := time.Now()
fmt.Printf("%-15s %-15s, %v\n", "DoNothing", note, t2.Sub(t1))
}
func main() {
cnt := 10000000 // ten million
testPrintf(ioutil.Discard, "discard.Attempt.1", cnt)
testPrintln(ioutil.Discard, "discard.Attempt.1", cnt)
testDoNothing(ioutil.Discard, "discard.Attempt.1", cnt)
fmt.Println("\n")
testPrintf(ioutil.Discard, "discard.Attempt.2", cnt)
testPrintln(ioutil.Discard, "discard.Attempt.2", cnt)
testDoNothing(ioutil.Discard, "discard.Attempt.2", cnt)
fmt.Println("\n")
testPrintf(ioutil.Discard, "discard.Attempt.3", cnt)
testPrintln(ioutil.Discard, "discard.Attempt.3", cnt)
testDoNothing(ioutil.Discard, "discard.Attempt.3", cnt)
}
--- 结果---
Printf discard.Attempt.1, 2.663697209s
Println discard.Attempt.1, 2.4289759s
DoNothing discard.Attempt.1, 190.480694ms
Printf discard.Attempt.2, 2.493506245s
Println discard.Attempt.2, 2.426081786s
DoNothing discard.Attempt.2, 182.899574ms
Printf discard.Attempt.3, 2.480853275s
Println discard.Attempt.3, 2.481552836s
DoNothing discard.Attempt.3, 180.916608ms
- 我每次跑了 1000 万次。
- 10M log to io 2~3 sec.Discard比我想象的要快..我想我不必担心速度。
- os.Stdout 我无意使用; (我最初担心的是使用 ioutil.Discard 保留代码与删除代码),但由于 os.Stdout 没有缓冲,所以速度很慢。
- 顺便说一句,printf() 比我想象的要快得多。几乎和 println() 一样
我不是每天都写 Go 代码,所以这个测试可能不准确。如果您从测试中看到误导性信息,请在此处发表评论以供其他人注意。谢谢。
【问题讨论】:
-
对于第一季度,您可以编写一个基准测试。然后你可以看到记录器有多慢。
-
对于第二季度,最好手动选择要记录的情况/错误,并且只记录那些(如果有的话)
-
如果你想知道性能影响,你需要在你的代码中测量它。评估日志参数占据您时间的可能性非常小。
-
您可以在 50 纳秒/日志条目下记录日志。例如github.com/larytet/binlog