Ho avuto il vantaggio di leggere le altre risposte. Per cominciare le persone come me dovrebbero sapere il motivo per cui abbiamo a che fare con un numero così grande qui è che entrambi Python
e bc
facciamo l' espansione esponenziale associativa giusta , il che significa che non 6^36
stiamo valutando, ma piuttosto 6^46656
che è considerevolmente più grande. 1
Usando le variazioni sui seguenti comandi, possiamo estrarre una media per un elemento specifico dell'output sia della time
parola riservata che del comando:
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}'
È possibile percorrere un'altra strada e rimuovere completamente il file dal confronto. Inoltre, possiamo confrontare i tempi di bc con qualcosa di simile al dc
comando, dato che storicamente il primo è un "processore front-end" con il secondo. I seguenti comandi sono stati cronometrati:
echo 6^6^6 | bc
echo 6 6 6 ^ ^ p | dc
echo print 6**6**6 | python2.7
Nota che il dc
comando è associativo di sinistra per l'espiazione. 2
Abbiamo alcuni risultati con time
(bash) per 1000 iterazioni (in secondi):
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
e dc
offrire prestazioni comparabili in questo contesto.
3 risultati meno accurati dal comando /usr/bin/time
GNU time
(la precisione della scala non è valida qui ma i risultati sono simili):
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
Un vantaggio /usr/bin/time
è che offre l' -v
opzione che fornisce molte più informazioni che potrebbero essere utili alla fine.
È anche possibile valutarlo internamente per così dire con il timeit
modulo 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
È un po 'più veloce di quello che abbiamo visto prima. Proviamo l'interprete stesso:
>>> 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
Questo è il più veloce che abbia mai visto.
Se valutiamo una minore esponenziazione come 6^6
, allora il comando time produce risultati sorprendenti - usando gli stessi for
comandi loop che abbiamo usato ora abbiamo:
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
Quindi con un numero intero più piccolo bc
è improvvisamente molto più veloce ?? Dal riavvio del sistema alla seconda esecuzione non fa differenza. Allo stesso tempo, se usiamo timeit
per Python, otteniamo:
python2.7 -m timeit -n 100000 -r 1 'print 6**6' | grep loops
100000 loops, best of 1: 0.468 usec per loop
Questo è microsecondi , non millisecondi, quindi non corrisponde ai risultati molto più lenti usando il for
loop. Forse sono necessari altri strumenti per testarlo ulteriormente e, come altri hanno spiegato, qui c'è molto di più di quello che si vede. Sembra che Python sia stato più veloce nello scenario della domanda, ma non è chiaro se si possano trarre conclusioni oltre quella ...
1. Inutile dire che va oltre lo scopo di qualcosa come l'espansione aritmetica dell'eco, per esempio echo $((6**6**6))
- bash
sembra essere anche associativo per quello, cioè 6^6^6 = 6^(6^6)
.
2. Confrontare con questo: 6 6 ^ 6 ^ p
.
3. È possibile che il comando GNU time fornisca ulteriori informazioni quando eseguito su BSD UNIX (documento informativo sul tempo GNU): la maggior parte delle informazioni mostrate da 'time' derivano dalla chiamata di sistema 'wait3'. I numeri sono buoni solo come quelli restituiti da 'wait3'. Molti sistemi non misurano tutte le risorse su cui "tempo" può riferire; tali risorse sono riportate come zero. I sistemi che misurano la maggior parte o tutte le risorse si basano su 4.2 o 4.3BSD. Le versioni successive di BSD utilizzano un codice di gestione della memoria diverso che misura meno risorse. - Sui sistemi che non dispongono di una chiamata "wait3" che restituisce informazioni sullo stato, viene invece utilizzata la chiamata di sistema "times". Fornisce molte meno informazioni di "wait3", quindi in quei sistemi il "tempo" riporta la maggior parte delle risorse come zero.