Miałem tę zaletę, że przeczytałem inne odpowiedzi. Na początek ludzie tacy jak ja, powinien wiedzieć, dlaczego mamy do czynienia z tak wielką liczbą całkowitą jest to, że zarówno Python
i bc
zrobić prawym asocjacyjną ekspansję potęgowanie, co oznacza, że to nie 6^36
my oceny, lecz 6^46656
która jest znacznie większa. 1
Używając wariantów następujących poleceń, możemy wyodrębnić średnią dla określonego elementu wyniku zarówno time
słowa zarezerwowanego, jak i polecenia:
for i in {1..1000}; do (time echo 6^6^6 | bc > /dev/null) 2>&1; done | grep 'rea' | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
for i in {1..1000}; do (/usr/bin/time -v sh -c 'echo 6^6^6 | bc > /dev/null') 2>&1; done | grep 'Use' | sed -e s/.*:// | awk '{sum += $1} END {print sum / NR}'
Można przejść inną trasę i całkowicie usunąć plik z porównania. Możemy także porównać czas bc z czymś takim jak dc
polecenie, ponieważ historycznie ten pierwszy jest „procesorem front-end” do drugiego. Nastąpiły następujące komendy:
echo 6^6^6 | bc
echo 6 6 6 ^ ^ p | dc
echo print 6**6**6 | python2.7
Zauważ, że dc
polecenie ma lewy asocjatywny dla potęgowania. 2)
Mamy kilka wyników dla time
(bash) dla 1000 iteracji (w sekundach):
0.229678 real bc
0.228348 user bc
0.000569 sys bc
0.23306 real dc
0.231786 user dc
0.000395 sys dc
0.07 real python
0.065907 user python
0.003141 sys python
bc
i dc
oferują porównywalną wydajność w tym kontekście.
Mniej dokładne 3 wyniki z /usr/bin/time
np. time
Polecenia GNU (dokładność skali nie jest tutaj poprawna, ale wyniki są podobne):
0.2224 user bc
0 sys bc
0.23 Elapsed bc
0.22998 user dc
0 sys dc
0.23 Elapsed dc
0.06008 user python
0 sys python
0.07 Elapsed python
Zaletą /usr/bin/time
jest to, że oferuje -v
opcję, która daje znacznie więcej informacji, które mogą być przydatne w końcu.
Można również ocenić to wewnętrznie , aby porozmawiać z timeit
modułem Python:
python2.7 -m timeit -n 1000 -r 1 'print 6**6**6' | grep 'loops'
1000 loops, best of 1: 55.4 msec per loop
To trochę szybciej niż to, co widzieliśmy wcześniej. Spróbujmy samego tłumacza:
>>> import timeit
>>> import sys
>>> import os
>>> T = timeit.Timer("print 6**6**6")
>>> n = int(1000)
>>> f = open(os.devnull, 'w')
>>> sys.stdout = f
>>> t = t.timeit(n)
>>> sys.stdout = sys.__stdout__
>>> print t/n
0.0553743481636
To najszybszy jaki widziałem.
Jeśli ocenimy mniejszą potęgowanie 6^6
, to polecenie czasowe daje zaskakujące wyniki - używając tych samych for
poleceń pętli, które teraz używamy:
0.001001 bc real
0.000304 user
0.000554 sys
0.014 python real i.e. 10x more than bc??
0.010432 user
0.002606 sys
Więc przy mniejszej liczbie całkowitej bc
jest nagle znacznie szybsze? Od ponownego uruchomienia systemu do drugiego uruchomienia nie ma znaczenia. Jednak jednocześnie, jeśli używamy timeit
Pythona, otrzymujemy:
python2.7 -m timeit -n 100000 -r 1 'print 6**6' | grep loops
100000 loops, best of 1: 0.468 usec per loop
Są to mikrosekundy , a nie milisekundy, więc nie pasuje to do znacznie wolniejszych wyników w for
pętli. Być może potrzebne są inne narzędzia do dalszego testowania, a jak wyjaśnili inni, tutaj jest więcej niż na pierwszy rzut oka. Wygląda na to, że Python był szybszy w scenariuszu pytania, ale nie jest jasne, czy można wyciągnąć wnioski poza tym ...
1. Nie trzeba dodawać, że wykracza poza zakres czegoś takiego jak ekspansja arytmetyczna echa, tj. echo $((6**6**6))
- bash
zdarza się również, że jest do tego słusznie asocjatywna, tj 6^6^6 = 6^(6^6)
.
2. Porównaj z tym: 6 6 ^ 6 ^ p
.
3. Możliwe jest, że polecenie czasu GNU dostarcza więcej informacji, gdy jest uruchamiane w systemie BSD UNIX (dokument informacji o czasie GNU): Większość informacji wyświetlanych jako „czas” pochodzi z wywołania systemowego „wait3”. Liczby są tak dobre, jak te zwracane przez „wait3”. Wiele systemów nie mierzy wszystkich zasobów, o których „czas” może informować; zasoby te są zgłaszane jako zero. Systemy mierzące większość lub wszystkie zasoby oparte są na 4.2 lub 4.3BSD. Późniejsze wersje BSD używają innego kodu zarządzania pamięcią, który mierzy mniej zasobów. - W systemach, które nie mają wywołania „wait3”, które zwraca informacje o statusie, zamiast tego używane jest wywołanie systemowe „times”. Dostarcza znacznie mniej informacji niż „wait3”, więc w tych systemach „czas” zgłasza większość zasobów jako zero.