Testare il tempo di esecuzione degli algoritmi in JAVA

sun-java-logoTalvolta per motivi di studio mi capita di lavorare con JAVA. Per chi non lo sapesse, JAVA è forse uno dei linguaggi di programmazione orientata agli oggetti più apprezzato al mondo, vuoi per la sua portabilità, vuoi per la sua facile comprensione, è sicuramente un importante punto di riferimento per chi deve imparare a programmare seguendo le solide e rigide basi della OOP.

A tal proposito vi ricordo la mini introduzione sui linguaggi OOP che ho redatto ormai un anno fa, che comprende alcune basi quali le classi, le interfacce e l’ereditarietà.

Tornando a noi, spesso lavorando in JAVA mi è capitato di dover calcolare il tempo di esecuzione di un determinato segmento di codice. Il metodo più semplice in assoluto che ho trovato è stato quello di utilizzare il metodo nanoTime della classe System.

long time = System.nanoTime();

Il valore riportato da questa funzione altro non è che il tempo attuale (calcolato in base alla data e ora di sistema e basato sul clock del processore) in nanosecondi. Questo codice può fungere da semplice esempio:


long time = System.nanoTime();

for (int i = 0; i < 100000000; i++) {

//non fa nulla

}

System.out.println("Tempo trascorso: "+(System.nanoTime()-time)+" ns");

Nel mio caso particolare il sistema mi riporta in uscita questa scritta “Tempo trascorso: 58570363 ns”

Ovviamente possiamo utilizzare questa soluzione per testare algoritmi ben più interessanti di quello riportato qui. Buon lavoro! ok emoticon

This entry was posted in JAVA, Programmazione and tagged , , , , , , , , , , . Bookmark the permalink.

2 Responses to Testare il tempo di esecuzione degli algoritmi in JAVA

  1. Enrico says:

    Attento!
    System.nanoTime() NON ha una accuratezza dei nanosecondi. come scritto nelle api

    This method provides nanosecond precision, but not necessarily nanosecond accuracy

    Questo significa che se vuoi avere una misura con precisione il problema è decisamente più complesso.
    Ricordo che la JVM ottimizza durante la loro esecuzione (alcune implementazioni usano JIT, quella della Sun utilizza un sistema di ottimizzazione implementato da HotSpot). Il che significa che uguali codici non sempre hanno lo stesso tempo di esecuzione! Infatti questo dipende da:
    - l’implementazione della JVM
    - versione della stessa
    - tempo di esecuzione di System.nanoTime (presumo che la sua implementazione vada a fare una chiamata ad api native del sistema operativo, ma di questo non sono sicuro)

    … nel caso poi il codice è rappresentato da un ciclo che usi alcune variabili (quindi non vuoto come quello proposto) il tempo varia anche dalla dimensione della cache e dalla politica di rimpiazzamento. Di solito si utilizza una LRU il che significa che dopo il primo ciclo l’accesso a variabili vicine (che in generale siano nella stessa cache line caricata) risulta decisamente più veloce. (PS: la JVM non assicura che varibile dichiarate “vicine” vengano allocate in memoria “vicino”. Ad esempio dichiarando un vettore di 100 elementi, non è detto che questi siano contigui in memoria, anche se dalla mia esperienza posso dire che la maggior parte delle implementazioni le mette in aree contigue )

    Ovviamente, poi, la misura data dalla differenza di 2 tempi è influenzata anche dal numero di altri processi in esecuzione nella macchina stessa.

    Cmq devo dire che System.nanoTime rappresenta un passo per avere una idea di tempistica!
    Enrico

  2. Denis says:

    Ciao Enrico, innanzitutto grazie per il tuo intervento, devo dire che è uno dei più azzeccati che abbia avuto! In realtà questo articolo è in relazione ad uno simile che ho scritto per C#, dove lì ho scritto che effettivamente il metodo proposto non è assolutamente il migliore, ma serve per avere un’idea sulle tempistiche di esecuzione dell’algoritmo. Anche perchè, lavorando proprio in questi giorni su algoritmi che hanno a che fare con grandi numeri primi e diverse esponenziazioni modulari (tutte cose riguardanti algoritmi asimmetrici come RSA), ho avuto modo di notare che spesso lo stesso algoritmo ha tempistiche completamente differenti, che dipendono dal fatto che la JVM crea una cache delle variabili e dei valori che utilizza maggiormente ed altri fattori che sinceramente non conosco. System.nanoTime() quindi, come dici giustamente anche tu, dà un’idea… è chiaro che per poter avere un modello totalmente estraneo all’ambiente JAVA, occorre implementare qualcosa di molto più complesso e di cui non credo parlerò mai in questa sede… diciamo che lo lascio come spunto per il lettore wink emoticon

    A presto!

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

*

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>