2017-05-12 3 views
0

Je suis intéressé à comparer la vitesse de deux fonctions différentes, en utilisant les mêmes données d'entrée (BMP) pour les deux fonctions.Doit-on mesurer le temps d'exécution moyen ou minimum d'une fonction?


Quand on mesure le temps d'exécution d'une fonction (en utilisant toujours même entrée) nous ne recevons pas le même résultat (temps), même si nous parce que le programme se déroule dans un environnement multi-tâches. Même si notre programme est «hautement prioritaire», certaines interférences avec d'autres programmes ralentiront notre programme (pour simplifier, considérons un ordinateur central). Donc, la plupart des gens chronomètrent la fonction plusieurs fois et font une moyenne. Ma question est pourquoi ne pas enregistrer le plus petit temps d'exécution au lieu de la moyenne? Le temps d'exécution min devrait être beaucoup plus proche de la réalité que le temps d'exécution moyen.

+0

Il ne reflète que le temps réel d'exécution s'il n'y a pas de chemins d'exécution différents.Un chemin d'exécution pourrait être beaucoup plus long/plus lent que l'autre. Le plus court (dans le temps) pourrait, par exemple, être simplement un retour anticipé si certaines conditions ne sont pas remplies. Cela ne reflète pas le temps d'exécution typique, et c'est ce que la plupart des gens veulent savoir. Prenez, par exemple, mon BigInteger.divide(). Si le diviseur transmis est nul, le temps d'exécution est très court. Mais il peut tout aussi bien être * très * long si ce n'est pas le cas. –

+1

L'existence de temps d'exécution plus longs est une preuve que la fonction peut prendre plus de temps que le minimum mesuré. La plupart des gens s'intéressent à la performance sous une charge arbitraire à des moments arbitraires. –

+0

Désolé. Je n'ai pas assez bien défini le problème. J'ai ajouté ceci: "mesurer le temps d'exécution d'une fonction (en utilisant toujours la même entrée)" - Donc, il n'y a plus de chemins d'exécution différents. Encore pardon. – Ampere

Répondre

1

Vous devriez toujours viser à chronométrer le temps minimum.
Parce que si vous le faites, vous êtes sûr de ne synchroniser que votre propre code et rien d'autre.

But pour un minimum de temps
Si votre code ne comporte qu'un seul chemin d'exécution, vous devez toujours prendre le temps minimum (de très nombreuses répétitions) que le temps réel pris.
De cette façon, vous pouvez obtenir des temps précis avec un ou deux cycles CPU. Juste pour être clair, vous exécutez l'extrait de code pour des millions de courses et prenez l'échantillon le plus bas de cette course comme timing.
Ensuite, vous enveloppez ces millions de passages dans une boucle qui s'exécute 10x ou 100x et prend à nouveau le minutage le plus bas. Comme si:

Lowest = MaxInt; 
loop 100x 
    loop million times 
    Clock.Start; 
    DoTest; 
    Timing = Clock.Time; 
    if (timing < Lowest) {Lowest = timing} 

L'autre boucle réinitialise le contexte qui aide parfois. Cela compte par ex. si le compilateur JIT démarre tard. La boucle externe lui donne un changement à réinitialiser.

Vous pouvez également définir vos horaires dans la boucle externe, puis diviser par un million si l'extrait de code est particulièrement rapide. Dans ce cas, vous allez exécuter une boucle de synchronisation vide supplémentaire et soustraire le temps pris par la boucle vide du temps pris dans la boucle occupée.
Il va falloir être intelligent pour éviter que l'optimisation du code n'élimine la boucle vide :-).

Si votre code a plusieurs chemins possibles, vous ne pouvez pas vraiment chronométrer son temps d'exécution. Exécution d'une simple boucle avec une entrée fixe, car cela ne vous donnera qu'un temps partiel d'un seul chemin de code. Ce n'est probablement pas représentatif de la performance du monde réel.

Faites vos courses déterministes
toujours essayer corriger le code donc il n'y a qu'un seul chemin le code peut prendre.
Ou essayez de configurer le test pour que tous les chemins possibles soient suivis successivement, puis chronométriez le temps minimum pour tout et divisez par le nombre de chemins de code testés.

Tout et l'évier de cuisine profilage
Si ce n'est pas possible, vous devrez prendre la moyenne, mais notez que dans ce cas, vous n'êtes pas vraiment timing juste votre code plus, vous prenez également le système les frais généraux, les interruptions du disque dur et les processus d'arrière-plan.