Basi di Temporizzazione e Benchmarking
Poiché in questo corso non ci concentriamo sull'analisi della complessità temporale, ci focalizzeremo su metodi empirici (pratici) per misurare le prestazioni effettive del codice. Uno dei modi più semplici per misurare le prestazioni di un frammento di codice è utilizzare la funzione incorporata time.time().
Questa funzione restituisce il tempo attuale in secondi dall'epoca (il punto di riferimento temporale del sistema). Chiamando time.time() prima e dopo un blocco di codice, è possibile calcolare la differenza per vedere quanto tempo impiega ad essere eseguito.
123456789101112131415import time # Record the start time start_time = time.time() # Code you want to measure result = [x**2 for x in range(1000000)] # Record the end time end_time = time.time() # Calculate the difference to get the execution time execution_time = end_time - start_time print(f'Execution time: {execution_time} seconds')
Sebbene l'utilizzo di time.time() sia semplice ed efficace per stime approssimative, presenta diverse limitazioni:
- Bassa risoluzione: la precisione di
time.time()può variare a seconda del sistema operativo, portando a risultati imprecisi per operazioni di breve durata; - Overhead: include anche altri processi di sistema in esecuzione in background, che possono alterare la misurazione;
- Non ripete: per misurazioni più accurate, spesso è necessario eseguire lo stesso codice più volte per ottenere un valore medio, cosa che
time.time()non gestisce automaticamente.
Vantaggi dell'utilizzo di timeit
Il modulo timeit è uno strumento più avanzato progettato per superare le limitazioni di time.time() e fornire un modo affidabile per misurare il tempo di esecuzione di piccoli frammenti di codice, spesso indicati come micro-benchmarking.
I principali vantaggi di timeit sono:
-
Alta precisione:
timeitutilizzatime.perf_counter()internamente, un timer ad alta risoluzione che include il tempo trascorso durante il sonno e l'attesa di I/O, rendendolo più accurato per intervalli brevi rispetto atime.time(); -
Ripetizione automatica:
timeitesegue automaticamente il codice più volte e calcola il tempo medio di esecuzione. Questo aiuta a mitigare gli effetti dei processi in background, fornendo una misura più affidabile delle prestazioni del codice; -
Overhead minimo:
timeitè progettato per essere eseguito in un ambiente pulito, disabilitando temporaneamente la garbage collection per garantire che le misurazioni si concentrino sul codice sottoposto a benchmark senza interferenze dalle operazioni di gestione della memoria.
1234567import timeit # Code snippet to test code_snippet = 'result = [x**2 for x in range(1000000)]' # Running timeit to measure execution time iterations = 30 execution_time = timeit.timeit(code_snippet, number=iterations) print(f'Average Execution Time: {execution_time / iterations} seconds')
In questo esempio, timeit.timeit() esegue il codice specificato come stringa (variabile code_snippet) 30 volte (specificato dal parametro number) e restituisce il tempo totale di esecuzione per tutte le 30 esecuzioni. Dividendo il tempo totale per il numero di iterazioni (30), è possibile calcolare il tempo medio di esecuzione per una singola esecuzione.
Scelta del Numero di Iterazioni
La scelta del numero di iterazioni dipende dalla complessità del codice che si sta analizzando e dalla precisione richiesta nei risultati di temporizzazione. Eseguire il codice con diversi numeri di iterazioni consente di valutare la stabilità dei risultati; se i tempi di esecuzione sono costanti, probabilmente è stato trovato un numero di iterazioni ottimale.
Per frammenti di codice molto veloci (millisecondi o meno), puntare a 1000+ iterazioni per ottenere medie affidabili. Per codice di durata moderata (alcuni millisecondi fino a secondi), da 100 a 500 iterazioni dovrebbero essere sufficienti. Per codice a esecuzione più lunga (diversi secondi o più), da 10 a 50 iterazioni di solito offrono un buon equilibrio tra accuratezza e tempo impiegato per il benchmarking.
1. Quale funzione offre alta precisione ed esegue automaticamente il codice più volte per calcolare un tempo medio di esecuzione?
2. Perché l'utilizzo di time.time() per la misurazione delle prestazioni potrebbe essere meno affidabile rispetto a timeit.timeit()?
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione
Can you explain how to use the timeit module with functions instead of code strings?
What are some best practices for benchmarking code performance in Python?
Can you provide more examples of using timeit for different types of code?
Awesome!
Completion rate improved to 7.69
Basi di Temporizzazione e Benchmarking
Scorri per mostrare il menu
Poiché in questo corso non ci concentriamo sull'analisi della complessità temporale, ci focalizzeremo su metodi empirici (pratici) per misurare le prestazioni effettive del codice. Uno dei modi più semplici per misurare le prestazioni di un frammento di codice è utilizzare la funzione incorporata time.time().
Questa funzione restituisce il tempo attuale in secondi dall'epoca (il punto di riferimento temporale del sistema). Chiamando time.time() prima e dopo un blocco di codice, è possibile calcolare la differenza per vedere quanto tempo impiega ad essere eseguito.
123456789101112131415import time # Record the start time start_time = time.time() # Code you want to measure result = [x**2 for x in range(1000000)] # Record the end time end_time = time.time() # Calculate the difference to get the execution time execution_time = end_time - start_time print(f'Execution time: {execution_time} seconds')
Sebbene l'utilizzo di time.time() sia semplice ed efficace per stime approssimative, presenta diverse limitazioni:
- Bassa risoluzione: la precisione di
time.time()può variare a seconda del sistema operativo, portando a risultati imprecisi per operazioni di breve durata; - Overhead: include anche altri processi di sistema in esecuzione in background, che possono alterare la misurazione;
- Non ripete: per misurazioni più accurate, spesso è necessario eseguire lo stesso codice più volte per ottenere un valore medio, cosa che
time.time()non gestisce automaticamente.
Vantaggi dell'utilizzo di timeit
Il modulo timeit è uno strumento più avanzato progettato per superare le limitazioni di time.time() e fornire un modo affidabile per misurare il tempo di esecuzione di piccoli frammenti di codice, spesso indicati come micro-benchmarking.
I principali vantaggi di timeit sono:
-
Alta precisione:
timeitutilizzatime.perf_counter()internamente, un timer ad alta risoluzione che include il tempo trascorso durante il sonno e l'attesa di I/O, rendendolo più accurato per intervalli brevi rispetto atime.time(); -
Ripetizione automatica:
timeitesegue automaticamente il codice più volte e calcola il tempo medio di esecuzione. Questo aiuta a mitigare gli effetti dei processi in background, fornendo una misura più affidabile delle prestazioni del codice; -
Overhead minimo:
timeitè progettato per essere eseguito in un ambiente pulito, disabilitando temporaneamente la garbage collection per garantire che le misurazioni si concentrino sul codice sottoposto a benchmark senza interferenze dalle operazioni di gestione della memoria.
1234567import timeit # Code snippet to test code_snippet = 'result = [x**2 for x in range(1000000)]' # Running timeit to measure execution time iterations = 30 execution_time = timeit.timeit(code_snippet, number=iterations) print(f'Average Execution Time: {execution_time / iterations} seconds')
In questo esempio, timeit.timeit() esegue il codice specificato come stringa (variabile code_snippet) 30 volte (specificato dal parametro number) e restituisce il tempo totale di esecuzione per tutte le 30 esecuzioni. Dividendo il tempo totale per il numero di iterazioni (30), è possibile calcolare il tempo medio di esecuzione per una singola esecuzione.
Scelta del Numero di Iterazioni
La scelta del numero di iterazioni dipende dalla complessità del codice che si sta analizzando e dalla precisione richiesta nei risultati di temporizzazione. Eseguire il codice con diversi numeri di iterazioni consente di valutare la stabilità dei risultati; se i tempi di esecuzione sono costanti, probabilmente è stato trovato un numero di iterazioni ottimale.
Per frammenti di codice molto veloci (millisecondi o meno), puntare a 1000+ iterazioni per ottenere medie affidabili. Per codice di durata moderata (alcuni millisecondi fino a secondi), da 100 a 500 iterazioni dovrebbero essere sufficienti. Per codice a esecuzione più lunga (diversi secondi o più), da 10 a 50 iterazioni di solito offrono un buon equilibrio tra accuratezza e tempo impiegato per il benchmarking.
1. Quale funzione offre alta precisione ed esegue automaticamente il codice più volte per calcolare un tempo medio di esecuzione?
2. Perché l'utilizzo di time.time() per la misurazione delle prestazioni potrebbe essere meno affidabile rispetto a timeit.timeit()?
Grazie per i tuoi commenti!