首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有一种有效的方法来计算金刚的执行时间?

问有没有一种有效的方法来计算金刚的执行时间?
EN

Stack Overflow用户
提问于 2017-08-19 00:34:12
回答 4查看 44K关注 0票数 53

我在寻找计算go中执行时间的最佳方法。

代码语言:javascript
复制
func main() {
    start := time.Now()

    time.Sleep(time.Second * 2)

    //something doing here

    elapsed := time.Since(start)
    fmt.Printf("page took %s", elapsed)
}

上面的代码运行良好。

但是当我使用模板时,我必须再次为每个模板函数编写它。

是否有一种计算执行时间(包括模板)的高效方法?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-19 01:02:08

如果您正在对整个函数进行计时,那么可以使用defer来消除一些重复的代码。

代码语言:javascript
复制
// timer returns a function that prints the name argument and 
// the elapsed time between the call to timer and the call to
// the returned function. The returned function is intended to
// be used in a defer statement:
//
//   defer timer("sum")()
func timer(name string) func() {
    start := time.Now()
    return func() {
        fmt.Printf("%s took %v\n", name, time.Since(start))
    }
}

func main() {
    defer timer("main")()  // <-- The trailing () is the deferred call
    time.Sleep(time.Second * 2)
}   // prints: main took 2s

在操场上运行示例。

The 规范说这是关于延迟调用的。

每次“延迟”语句执行时,调用的函数值和参数都会像往常一样重新计算并重新保存,但实际函数不会被调用。相反,延迟函数将在周围函数返回之前立即调用,

函数值timer("main")是在defer语句中计算的。timer函数记录当前时间并返回一个匿名函数。返回的匿名函数将在周围函数返回之前立即调用。匿名函数计算并打印经过的时间。

使用runtime.Callers和runtime.CallersFrames自动获取调用函数的名称。

代码语言:javascript
复制
// callerName returns the name of the function skip frames up the call stack.
func callerName(skip int) string {
    const unknown = "unknown"
    pcs := make([]uintptr, 1)
    n := runtime.Callers(skip+2, pcs)
    if n < 1 {
        return unknown
    }
    frame, _ := runtime.CallersFrames(pcs).Next()
    if frame.Function == "" {
        return unknown
    }
    return frame.Function
}

// timer returns a function that prints the name of the calling
// function and the elapsed time between the call to timer and
// the call to the returned function. The returned function is
// intended to be used in a defer statement:
//
//   defer timer()()
func timer() func() {
    name := callerName(1)
    start := time.Now()
    return func() {
        fmt.Printf("%s took %v\n", name, time.Since(start))
    }
}

func main() {
    defer timer()()
    time.Sleep(time.Second * 2)
}   // prints: main.main took 2s

请注意,与使用字符串文本相比,获得函数名需要花费运行时成本,如本答案的第一部分所示。为了避免测量获取函数名的成本,timer在记录开始时间之前获取名称。

在操场上运行示例。

票数 116
EN

Stack Overflow用户

发布于 2017-08-19 16:05:38

贝塔·达雷尔提供的解决方案是完美的。

此外,如果不希望显式传递函数名,可以这样完成:

代码语言:javascript
复制
func SomeFunction(list *[]string) {
    defer TimeTrack(time.Now())
    // Do whatever you want.
}

func TimeTrack(start time.Time) {
    elapsed := time.Since(start)

    // Skip this function, and fetch the PC and file for its parent.
    pc, _, _, _ := runtime.Caller(1)

    // Retrieve a function object this functions parent.
    funcObj := runtime.FuncForPC(pc)

    // Regex to extract just the function name (and not the module path).
    runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
    name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")

    log.Println(fmt.Sprintf("%s took %s", name, elapsed))
}

因此,您将得到::

SomeFunction took 15.483µs

有关更多信息,请参阅本文:Go函数跟踪

分享知识。:)

票数 24
EN

Stack Overflow用户

发布于 2018-03-15 15:57:42

使用init函数

代码语言:javascript
复制
package main

import (
    "fmt"
    "time"
)

var start time.Time

func init() {
    start = time.Now()
}

func getChars(s string) {
    for _, c := range s {
        fmt.Printf("%c at time %v\n", c, time.Since(start))
        time.Sleep(10 * time.Millisecond)
    }
}

func main() {
    fmt.Println("main execution started at time", time.Since(start))

    getChars("Hello")

    fmt.Println("\nmain execution stopped at time", time.Since(start))
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45766572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档