#36: Calcolare il tempo di esecuzione di un frammento di codice (VB.NET)

Sviluppando o studiando una nuova tecnica, in un qualsiasi linguaggio di programmazione, spesso abbiamo bisogno di avere una valutazione oggettiva del tempo di esecuzione di più frammenti di codice, per poter valutare quale dei due impiega meno tempo. Infatti il minore tempo di esecuzione di certe parti di codice, specialmente quelle ripetute più volte nel corso del programma o utilizzate in più parti del programma stesso, ha per conseguenza un minore tempo di esecuzione dell’intero programma e quindi migliori prestazioni che vengono percepite positivamente dall’utente.

In questo post vedremo quindi come si crea e come si utilizza una classe in grado di memorizzare il momento iniziale di un test e la differenza tra un momento successivo e il momento iniziale.

La classe è la seguente:
 

Public Class Cronometro

   Private inizio As DateTime

   Private durata As TimeSpan

   Public Sub New()

      inizio = New DateTime

      durata = New TimeSpan

   End Sub

   Public Sub ferma()

      durata = CType(DateTime.Now.Subtract(inizio), TimeSpan)

   End Sub

   Public Sub avvia()

      GC.Collect()

      GC.WaitForPendingFinalizers()

      inizio = DateTime.Now

   End Sub

   Public ReadOnly Property Result() As TimeSpan

      Get

         Return durata

      End Get

   End Property

End Class

 

Le istruzioni GC.Collect() e GC.WaitForPendingFinalizers() servono per avviare la “raccolta della spazzatura” da parte del Garbage Collector, cioè l’eliminazione degli oggetti non più utilizzati. Infatti, come sappiamo, gli oggetti non vengono eliminati immediatamente al termine del loro utilizzo, ma rimangono in memoria finché il Garbage Collector non decide di eliminarli. In particolare la seconda istruzione (GC.WaitForPendingFinalizers) attende che siano terminati tutti i metodi Finalizer degli oggetti in corso di eliminazione.

Perché avviare esplicitamente il Garbage Collector? E’ presto detto: vogliamo che nel corso del nostro test non avvenga la “raccolta dei rifiuti” che rallenterebbe l’esecuzione e causerebbe l’invalidazione del test stesso.

In un’applicazione Console possiamo poi testare la classe Cronometro con questo codice:

Option Strict On

Imports System.Console

Module Module1

   Sub Main()

      Dim numeri(99999) As Integer

      BuildArray(numeri)

      Dim tObj As New Cronometro()

      tObj.avvia()

      ScriviNumeri(numeri)

      tObj.ferma()

      Console.WriteLine(“tempo in secondi: “ & _

         tObj.Result.TotalSeconds)

      Console.Read()

   End Sub

   Sub BuildArray(ByVal arr() As Integer)

      Dim indice As Integer

      For indice = 0 To 99999

         arr(indice) = indice

      Next

   End Sub

   Sub ScriviNumeri(ByVal arr() As Integer)

      Dim indice As Integer

      For indice = 0 To arr.GetUpperBound(0)

         Console.Write(arr(indice) & ” “)

      Next

   End Sub

End Module

 

Quella che abbiamo visto è la soluzione “classica” che viene spesso utilizzata e che, peraltro, va bene con qualsiasi linguaggio OOP (anche quelli non-.NET, fatti gli opportuni adattamenti).

E’ possibile ottenere una soluzione più ordinata e pulita utilizzando la classe System.Diagnostics.Stopwatch, implementata in tutti i Framework .NET dalla versione 2.0 in poi. Per esempio questo è il codice di un’applicazione Console che fa uso di tale classe:

Public Class Test

    Shared Sub main()

        Dim str As String = “”

        Dim watch As New System.Diagnostics.Stopwatch()

        watch.Start()     ‘ avvio del cronometro

        ‘ … fai qualcosa …

        Dim i As Integer = 0

        For i = 1 To 100

            str &= “*”

            Console.WriteLine(“<“ & str & “>”)

        Next

        watch.Stop()    ‘ stop del cronometro

        Console.WriteLine(“Tempo impiegato: “ + watch.Elapsed.ToString())

        Console.ReadLine()

    End Sub

End Class

 

Attenzione che il test può non funzionare perfettamente in tutti i casi: se il nostro computer è pieno di programmi e servizi in esecuzione, potremmo ottenere dei risultati non corretti. In particolare, quando dobbiamo confrontare i tempi di due versioni di codice diverse (per esempio due algoritmi di ordinamento diversi), lo stato del computer dovrebbe essere il più possibile uguale in entrambe le esecuzioni, altrimenti si rischia di falsare i risultati.

Il consiglio è sempre quello, se possibile, di utilizzare un’installazione “pulita”, con solo i programmi e i servizi indispensabili per l’esecuzione del programma e del relativo test.

 

Pubblicato il 12 giugno 2008, in Tips con tag , , . Aggiungi il permalink ai segnalibri. Lascia un commento.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: