2010-09-21 14 views
5

c'è qualche modo GNU valido su come misurare il tempo di esecuzione medio (caso peggiore, caso migliore) di qualche programma da riga di comando? Ho un filtro immagine, una quantità non specificata di immagini, filtrandole usando il ciclo for in bash. Finora sto usando il tempo , ma non riesco a trovare un modo per ottenere statistiche.Tempo medio di esecuzione

+0

@chown Qual è il punto del commento sopra? –

+1

Domanda simile che ha alcune buone risposte - [bash: tempo medio di esecuzione su un numero di esecuzioni] (http://stackoverflow.com/questions/8215482/mean-running-time-over-a-number-of-runs/ 8216082 # 8216082). – chown

risposta

4

C'è un interessante programma Perl chiamato dumbbench che è essenzialmente un wrapper attorno al comando time. Esegue il tuo programma un certo numero di volte, elimina i valori anomali, quindi calcola alcune statistiche.

L'autore ha un paio di articoli (here e here) che delineano a) perché il benchmarking fa schifo, e b) che tipo di grafici carini si possono fare per rendere i vostri numeri di benchmarking risucchiano un po 'meno.

+0

Spero solo di poter passare diversi parametri per ogni corsa, lo proverò stasera. –

2

Sei sulla strada giusta con time. È quello che uso per preformare le analisi di esecuzione di piccoli codici.

Quindi utilizzo python per raccogliere le statistiche leggendo l'output di time. Per aumentare la precisione, di solito eseguo il test da 10 a 1000 volte, a seconda della durata di ciascun processo.

Non ho familiarità con nessuna applicazione GNU preinstallata che faccia questo tipo di analisi.

+1

Se avete intenzione di usare Python, potreste voler usare [timeit] (http://www.python.org/doc//current/library/timeit.html). – GreenMatt

+1

Ai vecchi tempi, eseguivamo il programma 12 volte usando 'time', buttando fuori i momenti migliori e peggiori, poi facendo una media dei restanti 10 valori. –

+0

Amo timeit! Io raccomando di eseguire il piping dei dati da 'time' perché non voglio che Python controlli l'esecuzione dei miei comandi e quindi rallenti potenzialmente l'esecuzione catturando stdin e quant'altro. È un po 'come, dovrei usare C o dovrei usare Python: quel tipo di sensazione. – Sean

6

È possibile inviare l'output di tempo per qualche file, e poi "lavorare" il file

echo "some info" >> timefile.txt 
time (./yourprog parm1 parm2) 2>> timefile.txt 
+2

Non hai bisogno di parentesi. –

+0

Sul mio computer (bash versione 4.1.5 (1) -release (x86_64-pc-linux-gnu)), senza la parentesi, il '2 >>' si applica al programma interno – pmg

+0

@DennisWilliamson Lo stesso qui, anch'io * * fai ** bisogno del paren. – chown

2
#!/bin/bash 
for i in {1..100} 
do 
    env time --append -o time_output.txt ./test_program --arguments-to-test-program 
done 
exit 

Se si scopre che la {1..100} sintassi non funziona per voi allora dovresti dare un'occhiata al comando seq.

Ho utilizzato il env time per eseguire il programma orario anziché il comando incorporato della shell, che non accetta tutti gli argomenti che il programma orario impiega. Il programma orario impiega anche altri argomenti per modificare il formato del suo output, che probabilmente vorrai utilizzare per rendere i dati più facili da elaborare da un altro programma. L'argomento -p (--portability) lo rende in uscita nel formato POSIX (come fa il tempo incorporato di BASH), ma usando l'opzione -f puoi avere più controllo. man 1 time per maggiori informazioni.

Dopo aver raccolto i dati, un semplice script perl o python può facilmente analizzare e analizzare i dati di temporizzazione.

+0

Non è necessario utilizzare 'seq'. Puoi fare 'for ((i = 1; i <= 100; i ++))'. –

+0

Se possibile, voglio evitare di scrivere il mio stesso analizzatore se qualcun altro lo ha fatto. –

0

Si dovrebbe considerare se eseguire il ciclo esterno e dividere per le ripetizioni anziché cronometrare ciascuna iterazione separatamente. Se sei preoccupato di scartare l'alto e il basso, fai ancora qualche altra iterazione per soffocarlo.

time for i in {1..1000} 
do 
    something 
done 

È possibile capture the output from time in a variable:

foo=$({ time { 
    echo "stdout test message demo" 
    for i in {1..30} 
    do 
     something 
    done 
    echo "stderr test message demo" >&2 
} 1>&3 2>&4; } 2>&1) 

e fare un po 'di matematica falso:

foo=${foo/.}   # "divide" by ... 
echo "0.00${foo/#0}" # ... 1000 

o semplicemente usare bc:

echo "scale=8; $foo/1000" | bc