C'est une sorte de comparaison de performances étrange car généralement on mesure le temps qu'il faut pour calculer quelque chose de substantiel, plutôt que de voir combien d'itérations triviales on peut faire dans un certain laps de temps. J'ai eu du mal à faire fonctionner vos codes Python et Julia, j'ai donc modifié le code Julia pour qu'il fonctionne et je n'ai tout simplement pas exécuté le code Python. Comme l'a noté @chepner dans un commentaire, l'utilisation now()
et la comparaison de temps avec des DateTime
objets sont assez coûteuses. La time.time()
fonction Python renvoie simplement une valeur à virgule flottante. En fait, il y a une fonction Julia appelée time()
qui fait exactement la même chose:
julia> time()
1.587648091474481e9
Voici le timing de votre f()
fonction d' origine (modifiée pour fonctionner) sur mon système:
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
Il a fait près de 5 millions d'itérations avant la fin du temps. Comme je l'ai dit, je n'ai pas pu faire fonctionner votre code Python sur mon système sans bidouiller (ce que je n'ai pas pris la peine de faire). Mais voici une version de f()
cette utilisation à la time()
place, que j'appellerai avec imagination 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
Cette version a fait 36 millions d'itérations. Donc je suppose que Julia est plus rapide à boucler? Yay! Eh bien, en fait, le travail principal dans cette boucle est les appels à time()
donc ... Julia est plus rapide à générer beaucoup d' time()
appels!
Pourquoi est-il étrange de chronométrer cela? Comme je l'ai dit, la plupart du travail réel ici appelle time()
. Le reste de la boucle ne fait vraiment rien. Dans un langage compilé optimisé, si le compilateur voit une boucle qui ne fait rien, il l'éliminera complètement. Par exemple:
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, zéro seconde! Comment est-ce possible? Eh bien, regardons le code LLVM (un peu comme le code machine mais pour une machine imaginaire qui est utilisée comme représentation intermédiaire), cela diminue pour:
julia> @code_llvm h()
; @ REPL[16]:1 within `h'
define i64 @julia_h_293() {
top:
; @ REPL[16]:6 within `h'
ret i64 5000000050000000
}
Le compilateur voit la boucle, découvre que le résultat est le même à chaque fois et renvoie simplement cette valeur constante au lieu d'exécuter réellement la boucle. Ce qui, bien sûr, ne prend aucun temps.