samedi 1 décembre 2007

Benchmark en Ruby

Ma petite comparaison de l'autre jour entre les deux versions de la fonction triant 2 tableaux n'était pas rigoureuse dans la manière de mesurer les durées d'exécution. En effet, en mesurant le temps avec Time (.now en l'occurrence) on mesure le temps "système" c'est à dire dépendant fortement de tous les autres processus en cours sur le PC. Mais il y a mieux ! Faisons un petit tour par la doc...

Il existe en Ruby une façon propre d'effectuer des benchmarks, ou simplement des mesures de performances de scripts : la bibliothèque Benchmark.

Reprenons les deux méthodes melt de l'autre jour (en renommant la seconde melt2), avec un petit :
require 'benchmark'

On définit une fois pour toute nos deux tableaux a et b puis on lance le benchmark :

Benchmark.bm(9) do |timer|
timer.report('Algo naif') {for i in (0...10000)
melt a,b
end}
timer.report('Vrai Ruby') {for i in (0...10000)
melt2 a,b
end}
end
Le seul argument de bm est la longueur alloué à l'écriture des labels (optionnel). Ce coup-ci, j'ai lancé les méthodes 10000 fois, sans impression écran. Voyons le résultat :

user system total real
Algo naif 0.312000 0.000000 0.312000 ( 0.328000)
Vrai Ruby 0.016000 0.000000 0.016000 ( 0.016000)

Alors : la colonne real nous donne le temps que j'obtenais précédemment avec ma méthode avec Time : si elle est entre parenthèses, c'est qu'elle n'est pas très intéressante, dépendant fortement de votre environnement (autres jobs en cours...).
user donne le temps effectif à faire tourner l'interpréteur Ruby, et system les appels systèmes (ici il n'y en a pas : si j'avais imprimé les résultats à l'écran si, par exemple).
total fait la somme des 2 précédentes.

Assez simple pour obtenir une analyse plus rigoureuse des performances de vos codes. De plus, ça met ici bien en évidence que mon algo naïf était en fait bien moins performant que ce que je croyais : mea culpa.

La doc sur Benchmark.

0 commentaires: