Auf welche Weise kann ich eine Julia-Funktion bewerten?

11

Hintergrund

Ich habe mir selbst maschinelles Lernen beigebracht und mich vor kurzem mit dem Julia Machine Learning Ecosystem befasst.


Ich komme aus einem Python-Hintergrund und habe einige Erfahrungen mit Tensorflow und OpenCV / skimage. Ich möchte Julia ML-Bibliotheken (Flux / JuliaImages) mit ihren Gegenstücken vergleichen, um zu sehen, wie schnell oder langsam sie tatsächlich CV- Aufgaben ausführen, und um zu entscheiden, ob Ich sollte Julia verwenden.

Ich weiß, wie man sich die Zeit nimmt, um eine Funktion in Python mit einem timeitModul wie dem folgenden auszuführen :

#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

Wie vergleicht man die Ausführungszeit einer Funktion, die dieselbe Aufgabe in Julia ausführt, mit der entsprechenden Bibliothek (in diesem Fall JuliaImages)?

Bietet Julia eine Funktion / ein Makro für die Zeit / einen Benchmark?

PseudoCodeNerd
quelle

Antworten:

10

using BenchmarkToolsist die empfohlene Methode zum Benchmarking von Julia-Funktionen. Verwenden Sie eines @benchmarkoder die weniger ausführlichen @btimeMakros, die daraus exportiert wurden, es sei denn, Sie planen etwas, das eine Weile dauert . Da die Maschinerie hinter diesen Makros die Zielfunktion viele Male auswertet, @timeist sie nützlich für das Benchmarking von Dingen, die langsam ablaufen (z. B. wenn Festplattenzugriff oder sehr zeitaufwändige Berechnungen erforderlich sind).

Es ist wichtig zu verwenden @btimeoder @benchmarkrichtig, dies vermeidet irreführende Ergebnisse. Normalerweise vergleichen Sie eine Funktion, die ein oder mehrere Argumente akzeptiert. Beim Benchmarking sollten alle Argumente externe Variablen sein: (ohne das Benchmark-Makro)

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

Die Funktion wird viele Male ausgewertet. Um zu verhindern, dass die Funktionsargumente bei jeder Auswertung der Funktion neu ausgewertet werden, müssen wir jedes Argument markieren, indem wir $dem Namen jeder Variablen, die als Argument verwendet wird, ein a voranstellen. Die Benchmarking-Makros verwenden dies, um anzugeben, dass die Variable zu Beginn des Benchmarking-Prozesses einmal ausgewertet (aufgelöst) werden soll und das Ergebnis dann wie folgt direkt wiederverwendet werden soll:

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

Obwohl es Parameter gibt, die angepasst werden können, funktionieren die Standardwerte normalerweise gut. Weitere Informationen zu BenchmarkTools für erfahrene Benutzer finden Sie im Handbuch .

Jeffrey Sarnoff
quelle
7

Julia bietet zwei Makros für die Timing- / Benchmarking-Code-Laufzeit. Diese sind :

  • @Zeit
  • @benchmark : extern, installieren vonPkg.add("BenchmarkTools")

Die Verwendung von @benchmark von BenchmarkTools ist sehr einfach und würde Ihnen beim Vergleich der Geschwindigkeit der beiden Sprachen helfen. Beispiel für die Verwendung @bencharkgegen die von Ihnen bereitgestellte Python-Bank.

using Images, FileIO, BenchmarkTools

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

Ausgabe :

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

samplesUm nun die mittlere Zeit zu vergleichen, sollten Sie (46) als Zahl in Ihren Python-Timeit-Code einfügen und durch dieselbe Zahl dividieren, um die mittlere Ausführungszeit zu erhalten.

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

Sie können diesen Prozess zum Benchmarking jeder Funktion in Julia und Python befolgen. Ich hoffe, Sie haben Zweifel ausgeräumt.


Hinweis : Aus statistischer Sicht ist @benchmark viel besser als @time.

PseudoCodeNerd
quelle
2
Beachten Sie, dass das Timing-Rauschen meist positiv ist, was bedeutet, dass die Mindestzeit oft (nicht immer) informativer ist. @btimeund @belapsednur die Mindestzeit zurückgeben.
Fredrik Bagge