De quelle (s) manière (s) puis-je comparer une fonction Julia?

11

Contexte

Je me suis autodidacte apprentissage automatique et j'ai récemment commencé à me plonger dans l'écosystème Julia Machine Learning.


Venant d'un python et ayant une tensorflow et OpenCV / skimageexpérience, je veux référence bibliothèques Julia ML (Flux / JuliaImages) contre ses homologues pour voir à quelle vitesse ou ralentir vraiment exécute CV (tout) tâche (s) et de décider si Je devrais utiliser Julia.

Je sais comment obtenir le temps nécessaire pour exécuter une fonction en python en utilisant un timeitmodule comme celui-ci:

#Loading an Image using OpenCV

s = """\
img = cv2.imread('sample_image.png', 1)
"""
setup = """\
import timeit
"""
print(str(round((timeit.timeit(stmt = s, setup = setup, number = 1))*1000, 2)) + " ms")
#printing the time taken in ms rounded to 2 digits

Comment comparer le temps d'exécution d'une fonction effectuant la même tâche dans Julia en utilisant la bibliothèque appropriée (dans ce cas, JuliaImages).

Julia fournit-elle une fonction / macro à l'heure / référence?

PseudoCodeNerd
la source

Réponses:

10

using BenchmarkToolsest la méthode recommandée pour comparer les fonctions de Julia. Sauf si vous chronométrez quelque chose qui prend un certain temps, utilisez l'une @benchmarkou les @btimemacros moins verbeuses qui en sont exportées. Parce que la machinerie derrière ces macros évalue la fonction cible plusieurs fois, @timeest utile pour comparer les choses qui s'exécutent lentement (par exemple lorsque l'accès au disque ou des calculs très longs sont impliqués).

Il est important d'utiliser @btimeou @benchmarkcorrectement, cela évite les résultats trompeurs. Généralement, vous comparez une fonction qui prend un ou plusieurs arguments. Lors de l'analyse comparative, tous les arguments doivent être des variables externes: (sans la macro de référence)

x = 1
f(x)
# do not use f(1)

La fonction sera évaluée plusieurs fois. Pour éviter que les arguments de la fonction ne soient réévalués chaque fois que la fonction est évaluée, nous devons marquer chaque argument en préfixant a $au nom de chaque variable utilisée comme argument. Les macros d'analyse comparative utilisent ceci pour indiquer que la variable doit être évaluée (résolue) une fois, au début du processus d'analyse comparative, puis le résultat doit être réutilisé directement tel quel:

julia> using BenchmarkTools
julia> a = 1/2;
julia> b = 1/4;
julia> c = 1/8;
julia> a, b, c
(0.5, 0.25, 0.125)

julia> function sum_cosines(x, y, z)
         return cos(x) + cos(y) + cos(z)
       end;

julia> @btime sum_cosines($a, $b, $c);  # the `;` suppresses printing the returned value
  11.899 ns (0 allocations: 0 bytes)    # calling the function takes ~12 ns (nanoseconds)
                                        # the function does not allocate any memory
# if we omit the '$', what we see is misleading
julia> @btime sum_cosines(a, b, c);    # the function appears more than twice slower 
 28.441 ns (1 allocation: 16 bytes)    # the function appears to be allocating memory
# @benchmark can be used the same way that @btime is used
julia> @benchmark sum_cosines($a,$b,$c) # do not use a ';' here
BenchmarkTools.Trial:
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     12.111 ns (0.00% GC)
  median time:      12.213 ns (0.00% GC)
  mean time:        12.500 ns (0.00% GC)
  maximum time:     39.741 ns (0.00% GC)
  --------------
  samples:          1500
  evals/sample:     999

Bien qu'il existe des paramètres qui peuvent être ajustés, les valeurs par défaut fonctionnent généralement bien. Pour plus d'informations sur BenchmarkTools pour les urs expérimentés, consultez le manuel .

Jeffrey Sarnoff
la source
7

Julia propose deux macros pour le chronométrage / l'analyse comparative du code d'exécution. Ceux-ci sont :

  • @temps
  • @benchmark : externe, installez parPkg.add("BenchmarkTools")

L'utilisation de @benchmark de BenchmarkTools est très facile et vous serait utile pour comparer la vitesse des deux langues. Exemple d'utilisation par @bencharkrapport au banc python que vous avez fourni.

using Images, FileIO, BenchmarkTools

@benchmark img = load("sample_image.png")

Production :

BenchmarkTools.Trial: 
  memory estimate:  3.39 MiB
  allocs estimate:  322
  --------------
  minimum time:     76.631 ms (0.00% GC)
  median time:      105.579 ms (0.00% GC)
  mean time:        110.319 ms (0.41% GC)
  maximum time:     209.470 ms (0.00% GC)
  --------------
  samples:          46
  evals/sample:     1

Maintenant, pour comparer le temps moyen, vous devez mettre samples(46) comme nombre dans votre code timeit python et le diviser par le même nombre pour obtenir le temps moyen d'exécution.

print(str(round((timeit.timeit(stmt = s, setup = setup, number = 46)/46)*1000, 2)) + " ms")

Vous pouvez suivre ce processus pour comparer n'importe quelle fonction dans Julia et Python. J'espère que votre doute a été dissipé.


Remarque : d' un point de vue statistique, @benchmark est bien meilleur que @time.

PseudoCodeNerd
la source
2
Notez que le bruit de synchronisation est principalement positif, ce qui implique que le temps minimum est souvent (pas toujours) plus informatif. @btimeet @belapsedne retourner que le temps minimum.
Fredrik Bagge