Please ignore secret bonuses. Secret tests do NOT award bonus. Max hw grade is 30+2 bonus efficiency

Do you need help?

Notice Board

Per partecipare al corso di Fondamenti di programmazione 2023-24 loggatevi e attivatelo nella vostra pagina dei corsi preferiti. A quel punto il corso appare nel menù personale cliccando sul proprio avatar. Per i materiali degli anni precedenti seguite lo stesso metodo.

To join the Programming/Lab 2023-24 course, log-on and select it on the my courses page. It will appear on the personal menu of your avatar. For earlier years use the same method.

Misurare tempo esecuzione istruzioni

LorenzoChicca (1140 points)
5 6 18
in Programmare in Python by (1.1k points)
recategorized by
Salve,

fallisco per timeout i test dei miei script.

C'è un modo per analizzare i tempi passo passo? Ad esempio quanto tempo impiega una list comprehension, un ciclo for?

Grazie
1.2k views
closed

3 Answers

Best answer
a
alex_err (5800 points)
1 3 32
by (5.8k points)
selected by
C'è una fantastica funzione di Spyder che esegue il profiling della tua applicazione, e che se eseguita su test_01.py ti indica per ogni test i tempi di esecuzione delle singole funzioni.

Dimenticavo di dire che la puoi avviare dal menù Run → Profile (o semplicemente premendo F10).
E
Edward (25950 points)
4 4 172
by (26.0k points)

Se hai installato pytest-profiling puoi vedere le funzioni del programma che occupano più tempo.

Lo puoi fare usando il comando:
pytest -rA -v --profile test.py

Prima ti conviene però andare nel file C:\Users\NomeUtente\Anaconda3\Lib\site-packages\pytest_profiling.py (Windows 10)
E mettere questo

pstats.Stats(self.combined, stream=terminalreporter).strip_dirs().sort_stats('tottime').print_stats(20)

al posto di

pstats.Stats(self.combined, stream=terminalreporter).strip_dirs().sort_stats('cumulative').print_stats(20)

Per istruzioni su come installare pytest-profiling e altri comandi, leggi il post Software da Installare.

LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
Avevo gia provato. Ma nn mi dice nulla...

In pratica mi dice che program01.py impiega 1.990, poi sotto altre righe dal tempo di 0.001 o 0.000, quindi è inutile
E
Edward (25950 points)
4 4 172
by (26.0k points)
Per vedere le singole istruzioni quanto tempo impiegano, puoi usare il comando %timeit nella console iPython
Dovresti ad esempio fare %timeit [listcomprehension] e ti fa vedere quanto tempo ci mette
LorenzoChicca (1140 points)
5 6 18
by (1.1k points)

Allora ecco! Ho capito una cosa.

Vedevo tutti tempi 0.000 o 0.0001.
In alto mi dice: 

Ordered by: internal time
List reduced from 456 to 20 due to restriction <20>

Bisogna andare nel file
C:\Users\NomeUtente\Anaconda3\Lib\site-packages\pytest_profiling.py

e alla riga
pstats.Stats(self.combined, stream=terminalreporter).strip_dirs().sort_stats('tottime').print_stats(20)

anzicché mettere 20, mettere 456, come nel mio caso.

Comunque a parte la prima riga program01.py, in cui da il tempo che gia sappiamo, tutte le altre hanno tempo 0.000 o 0.001, quindi è inutile

E
Edward (25950 points)
4 4 172
by (26.0k points)
Sì così te li mette tutti... ma teoricamente mettendo totime invece di cumulative ti fa vedere per primi quelli che impiegano più tempo
LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
Mi fa vedere la prima che impiega 1.900, un paio 0.001, tutto il resto 0.000
E
Edward (25950 points)
4 4 172
by (26.0k points)

Comunque a parte la prima riga program01.py, in cui da il tempo che gia sappiamo, tutte le altre hanno tempo 0.000 o 0.001, quindi è inutile

Perchè quello ti dice quale funzione impiega più tempo, se tu hai scritto tutto in una funzione, ovviamente il risultato sarà che quella funzione impiega tutto il tempo.
Per testare singolarmente pezzetti di codice puoi provare ad usare %timeit, ma dovresti creare minifunzioni e simularne i dati di input

LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
Allora, avevo una funzione dentro es1(S,m), ho spostato questa funzione fuori dalla funzione, ma niente. Tutto uguale, mi dice program01.py, 1.700, tutto il resto 0.000
LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
Sto provando con il modulo time.time() per ora
E
Edward (25950 points)
4 4 172
by (26.0k points)
Sì credo che per funzionare la funzione deve essere dichiarata all'esterno.

Guarda a me quel comando funziona, mi elenca correttamente le funzioni che impiegano più tempo.
LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
Niente, ho messo anche degli time.sleep(1) per bloccare lo script ma niente. Funzioni dentro, fuori, destra e sinsitra. Niente.

Vedo solo program01.py 1.799, tutto il resto 0.000, salvo alcuni casi 0.001
E
Edward (25950 points)
4 4 172
by (26.0k points)

Hai provato nella scheda Correttezza del Risultato a vedere cosa dice?

LorenzoChicca (1140 points)
5 6 18
by (1.1k points)
La mia funzione ritorna in tutti i casi ul risultato corretto, solo che ci mette troppo tempo
E
Edward (25950 points)
4 4 172
by (26.0k points)
È il problema della maggior parte di noi quello!
plm (18850 points)
13 15 118
by (18.9k points)
Intendi dire quel comando che scritto nella consoli ti dice quanti secondi impiega? Perchè anche io non riesco a trovarlo, per cui mi interessa :)
E
Edward (25950 points)
4 4 172
by (26.0k points)
L'ho commentato più sopra, è %timeit