Próbowałem porównać te dwa fragmenty i zobaczyć, ile iteracji można wykonać w ciągu jednej sekundy. Okazuje się, że Julia osiąga 2,5 miliona iteracji, a Python 4 miliony. Czy Julia nie powinna być szybsza? A może te dwa fragmenty nie są równoważne?
Pyton:
t1 = time.time()
i = 0
while True:
i += 1
if time.time() - t1 >= 1:
break
Julia:
function f()
i = 0
t1 = now()
while true
i += 1
if now() - t1 >= Base.Dates.Millisecond(1000)
break
end
end
return i
end
Odpowiedzi:
Jest to swego rodzaju dziwne porównanie wydajności, ponieważ zwykle mierzy się czas potrzebny na obliczenie czegoś istotnego, zamiast sprawdzać, ile trywialnych iteracji można wykonać w określonym czasie. Miałem problem z uruchomieniem kodów Python i Julia, więc zmodyfikowałem kod Julia do pracy i po prostu nie uruchomiłem kodu Python. Jak zauważył @chepner w komentarzu, korzystanie
now()
i porównywanie czasu zDateTime
obiektami jest dość drogie. Funkcja Pythontime.time()
po prostu zwraca wartość zmiennoprzecinkową. Jak się okazuje, istnieje funkcja Julia,time()
która robi dokładnie to samo:Oto czas oryginalnej
f()
funkcji (zmodyfikowanej do pracy) w moim systemie:Wykonał prawie 5 milionów iteracji, zanim upłynął czas. Tak jak powiedziałem, nie byłem w stanie uruchomić twojego kodu Python w moim systemie bez znaczącego majsterkowania (czego nie zawracałem sobie głowy). Ale oto wersja,
f()
której używatime()
zamiast tego, którą wyobraźni nazywamg()
:Ta wersja wykonała 36 milionów iteracji. Więc myślę, że Julia jest szybsza w zapętlaniu? Tak! Cóż, właściwie główną pracą w tej pętli są wywołania,
time()
więc ... Julia szybciej generuje wieletime()
połączeń!Dlaczego czas jest taki dziwny? Jak już powiedziałem, większość faktycznej pracy tutaj to dzwonienie
time()
. Reszta pętli tak naprawdę nic nie robi. W optymalizowanym języku kompilatora, jeśli kompilator zobaczy pętlę, która nic nie robi, całkowicie ją wyeliminuje. Na przykład:Woah, zero sekund! Jak to możliwe? Spójrzmy na kod LLVM (coś w rodzaju kodu maszynowego, ale dla wyobrażonej maszyny używanej jako reprezentacja pośrednia), która obniża się do:
Kompilator widzi pętlę, stwierdza, że wynik jest za każdym razem taki sam, i po prostu zwraca tę stałą wartość zamiast faktycznego wykonania pętli. Co oczywiście zajmuje zero czasu.
źródło
Prawdopodobnie chcesz użyć
time_ns
funkcji w Julii:Na moim komputerze działa 10 razy szybciej niż Python.
źródło
Cóż, nie tego obserwuję w moim systemie:
Python 3.7.7
Julia 1.4.0:
ale zauważ, że samo użycie
time
(tj. porównanie liczb zwykłych) jest jeszcze szybsze:źródło
time.perf_counter_ns()
w Pythonie?time_ns
nietime
jak to jest ~ 30% szybszy.