web-dev-qa-db-fra.com

Comment chronométrez-vous une fonction dans Go et retournez-vous son exécution en millisecondes?

Comment chronométrez-vous une fonction dans Go et retournez-vous son exécution en millisecondes?

36
The Puma

Utilisez le package Go testing pour comparer la fonction. Par exemple,

package main

import (
    "fmt"
    "testing"
)

// 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 < b.N; i++ {
        _ = Function(n)
    }
}

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

Production:

500000000            4.22 ns/op

Vous pouvez également utiliser la commande Go gotest pour exécuter des tests de performances.

30
peterSO

Go's defer rend cela trivial.

Dans Go 1.x, définissez les fonctions suivantes:

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))
}

Après cela, vous obtenez des messages de journal du temps écoulé d'une ligne Squeaky Clean:

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

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

La magie intelligente est que la trace () est appelée au début de la fonction, mais l'un () est reporté à la fin. Ce n'est pas précis à l'horloge atomique, en raison des instructions du journal, mais si vous avez besoin de plus de précision, ce type de motif est l'une des bonnes forces de la guimauve de Go.

ÉDITER:

Cette réponse utilisait à l'origine l'API de package temporel hérité. Reproduit ici pour valeur historique seulement:

Pour une utilisation avec les versions Go avant le 12-01-2011 chaque semaine:

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)
}
32
amattn

Peut-être que vous pouvez également utiliser une durée (écoulée) pour cela ... semble un peu plus agréable.

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

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

Un autre moyen simple peut être:

import (
    "fmt"
    "time"
)

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

qui produira quelque chose comme 359.684612ms

11
Salvador Dali

Il existe plusieurs options pour l'horodatage et les minuteries dans le package horaire. Voir la documentation ici: http://golang.org/pkg/time/

1
TJD