如何在Go中计时一个函数并以毫秒为单位返回其运行时间?

huangapple go评论86阅读模式
英文:

How do you time a function in Go and return its runtime in milliseconds?

问题

如何在Go中计时一个函数并以毫秒为单位返回其运行时间?

英文:

How do you time a function in Go and return its runtime in milliseconds?

答案1

得分: 38

Go的defer使得这个变得简单。

在Go 1.x中,定义以下函数:

func trace(s string) (string, time.Time) {
    log.Println("START:", s)
    return s, time.Now()
}

func un(s string, startTime time.Time) {
    endTime := time.Now()
    log.Println("  END:", s, "ElapsedTime in seconds:", endTime.Sub(startTime))
}

之后,你会得到简洁的一行经过时间的日志信息:

func someFunction() {
    defer un(trace("SOME_ARBITRARY_STRING_SO_YOU_CAN_KEEP_TRACK"))

    //在这里做一些事情...
}

聪明的魔法是trace()在函数开始时被调用,但un()被延迟到最后。由于日志语句的存在,它并不是原子钟精确,但如果你需要更高的精确度,这种模式是Go的一个优势。

编辑:

这个答案最初使用了旧的time包API。这里只是为了历史价值而重现:

用于Go版本在2011年12月1日之前的周刊:

func trace(s string) (string, int64) {
    log.Println("START:", s)
    return s, time.Nanoseconds()
}

func un(s string, startTime int64) {
    endTime := time.Nanoseconds()
    log.Println("  END:", s, "ElapsedTime in seconds:", float32(endTime-startTime)/1E9)
}
英文:

Go's defer makes this trivial.

In Go 1.x, define the following functions:

func trace(s string) (string, time.Time) {
    log.Println("START:", s)
    return s, time.Now()
}

func un(s string, startTime time.Time) {
    endTime := time.Now()
    log.Println("  END:", s, "ElapsedTime in seconds:", endTime.Sub(startTime))
}

After that, you get Squeaky Clean one line elapsed time log messages:

func someFunction() {
    defer un(trace("SOME_ARBITRARY_STRING_SO_YOU_CAN_KEEP_TRACK"))

    //do a bunch of stuff here...
}

The clever magic is that the trace() is called at the beginning of the function, but the un() is deferred to the end. It's not atomic-clock accurate, due to the log statements, but if you need more accuracy, this kind of pattern is one of Go's marshmallowy good strengths.

EDIT:

This answer originally used legacy time package API. Reproduced here for historical value only:

For use w/ Go versions prior to 12-01-2011 weekly:

func trace(s string) (string, int64) {
    log.Println("START:", s)
    return s, time.Nanoseconds()
}

func un(s string, startTime int64) {
    endTime := time.Nanoseconds()
    log.Println("  END:", s, "ElapsedTime in seconds:", float32(endTime-startTime)/1E9)
}

答案2

得分: 31

使用Go testing包来对函数进行基准测试。例如,

package main

import (
	"fmt"
	"testing"
)

// 要进行基准测试的函数
func Function(n int) int64 {
	n64 := int64(n)
	return n64 * n64
}

func BenchmarkFunction(b *testing.B) {
	n := 42
	for i := 0; i < b.N; i++ {
		_ = Function(n)
	}
}

func main() {
	br := testing.Benchmark(BenchmarkFunction)
	fmt.Println(br)
}

输出:

500000000         4.22 ns/op

您还可以使用Go gotest命令来运行基准测试。

英文:

Use the Go testing package to benchmark the function. For example,

package main

import (
	&quot;fmt&quot;
	&quot;testing&quot;
)

// the function to be benchmarked
func Function(n int) int64 {
	n64 := int64(n)
	return n64 * n64
}

func BenchmarkFunction(b *testing.B) {
	n := 42
	for i := 0; i &lt; b.N; i++ {
		_ = Function(n)
	}
}

func main() {
	br := testing.Benchmark(BenchmarkFunction)
	fmt.Println(br)
}

Output:

500000000	         4.22 ns/op

You can also use the Go gotest command to run benchmarks.

答案3

得分: 17

另一种简单的方法可以是:

import (
    "fmt"
    "time"
)

start := time.Now()
// 进行一些计算
elapsed := time.Since(start)
fmt.Println(elapsed)

这将输出类似于 359.684612ms 的内容。

英文:

Another easy way can be:

import (
    &quot;fmt&quot;
    &quot;time&quot;
)

start := time.Now()
// some computation
elapsed := time.Since(start)
fmt.Println(elapsed)

which will output something like 359.684612ms

答案4

得分: 12

也许你也可以使用一个持续时间(经过的时间)来实现这个...看起来更好一些。

func trace(s string) (string, time.Time) {
    log.Printf("跟踪开始:%s\n", s)
    return s, time.Now()
}

func un(s string, startTime time.Time) {
    elapsed := time.Since(startTime)
    log.Printf("跟踪结束:%s,经过时间 %f 秒\n", s, elapsed.Seconds())
}
英文:

Perhaps you can also use a Duration (elapsed) for this...looks a little bit nicer.

func trace(s string) (string, time.Time) {
	log.Printf(&quot;trace start: %s\n&quot;, s)
	return s, time.Now()
}

func un(s string, startTime time.Time) {
	elapsed := time.Since(startTime)
	log.Printf(&quot;trace end: %s, elapsed %f secs\n&quot;, s, elapsed.Seconds())
}

答案5

得分: 1

有关时间戳和定时器的时间包有几个选项。请参阅此处的文档:http://golang.org/pkg/time/

英文:

There are several options for timestamping and timers in the time package. See the documentation here: http://golang.org/pkg/time/

huangapple
  • 本文由 发表于 2011年12月2日 09:13:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/8350609.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定