Dies ist eine Art seltsamer Leistungsvergleich, da man normalerweise die Zeit misst, die benötigt wird, um etwas Substanzielles zu berechnen, anstatt zu sehen, wie viele triviale Iterationen man in einer bestimmten Zeit durchführen kann. Ich hatte Probleme, Ihre Python- und Julia-Codes zum Laufen zu bringen, daher habe ich den Julia-Code so geändert, dass er funktioniert, und den Python-Code einfach nicht ausgeführt. Wie @chepner in einem Kommentar feststellte, ist die Verwendung now()
und Durchführung von Zeitvergleichen mit DateTime
Objekten ziemlich teuer. Die Python- time.time()
Funktion gibt nur einen Gleitkommawert zurück. Wie sich herausstellt, gibt es eine Julia-Funktion time()
, die genau dasselbe tut:
julia> time()
1.587648091474481e9
Hier ist das Timing Ihrer ursprünglichen f()
Funktion (geändert, um zu funktionieren) auf meinem System:
julia> using Dates
julia> function f()
i = 0
t1 = now()
while true
i += 1
if now() - t1 >= Millisecond(1000)
break
end
end
return i
end
f (generic function with 1 method)
julia> f()
4943739
Es wurden fast 5 Millionen Iterationen durchgeführt, bevor die Zeit abgelaufen war. Wie gesagt, ich konnte Ihren Python-Code nicht ohne nennenswerten Aufwand auf meinem System ausführen (was ich nicht getan habe). Aber hier ist eine Version , f()
dass Anwendungen time()
statt, die ich einfallsreich nennen g()
:
julia> function g()
i = 0
t1 = time()
while true
i += 1
if time() - t1 >= 1
break
end
end
return i
end
g (generic function with 1 method)
julia> g()
36087637
Diese Version hat 36 Millionen Iterationen durchgeführt. Also denke ich, Julia ist schneller im Looping? Yay! Nun, eigentlich ist die Hauptarbeit in dieser Schleife das Anrufen von time()
... Julia ist schneller darin, viele time()
Anrufe zu generieren !
Warum ist es seltsam, dies zu messen? Wie gesagt, die meiste Arbeit hier ruft an time()
. Der Rest der Schleife macht eigentlich nichts. Wenn der Compiler in einer optimierten kompilierten Sprache eine Schleife sieht, die nichts tut, wird sie vollständig entfernt. Zum Beispiel:
julia> function h()
t = 0
for i = 1:100_000_000
t += i
end
return t
end
h (generic function with 1 method)
julia> h()
5000000050000000
julia> @time h()
0.000000 seconds
5000000050000000
Woah, null Sekunden! Wie ist das möglich? Schauen wir uns das an LLVM-Code an (ähnlich wie Maschinencode, aber für eine imaginäre Maschine, die als Zwischendarstellung verwendet wird).
julia> @code_llvm h()
; @ REPL[16]:1 within `h'
define i64 @julia_h_293() {
top:
; @ REPL[16]:6 within `h'
ret i64 5000000050000000
}
Der Compiler sieht die Schleife, stellt fest, dass das Ergebnis jedes Mal das gleiche ist, und gibt nur diesen konstanten Wert zurück, anstatt die Schleife tatsächlich auszuführen. Was natürlich keine Zeit in Anspruch nimmt.