Cómo... en .NET

Stopwatch - una clase para calcular tiempos

Publicado el 19/Jul/2006
Actualizado el 20/Ene/2007
Autor: Guillermo 'guille' Som

En este artículo te explico para que sirve y cómo usar la clase Stopwatch de .NET 2.0.
Y como de costumbre, con código tanto para VB como para C#.

 

 

Introducción:

Antes de la versión 2.0 de .NET Framework, cuando queríamos hacer cálculos de tiempos, sobre todo si eran periodos cortos, teníamos que usar nuestro propio código.

Por ejemplo, en Visual Basic 6.0 y anteriores era habitual usar el API de Windows, particularmente la función timeGetTime, de hecho en su día publiqué la clase cGetTimer para ese propósito, que era facilitar el uso de esa función del API de Windows.
Pero esto de usar una función del API de Windows, es algo que con Visual Basic 2005 y C# 2.0 no es necesario, ya que el propio .NET 2.0 incluye una clase para realizar esa tarea.

La clase en cuestión es Stopwatch, (pulsando en el link irás a la página de MSDN de Microsoft en español en la que te explica todo sobre esta clase).

Esta clase tiene varios métodos de instancia: Start, Stop y Reset que sirven para iniciar, detener y resetear el temporizador respectivamente.
También tiene propiedades de instancia para saber el tiempo transcurrido: Elapsed, que devuelve un objeto de tipo TimeSpan, ElapsedMilliseconds que devuelve un valor Long con los milisegundos transcurridos y ElapsedTicks que también devuelve un valor Long, pero con los "pasos" del temporizador.
Además, la propiedad IsRunnig nos puede servir para saber si aún se está ejecutando.

Además de todos estos miembros de instancia, es decir, aplicables a nuevos objetos creados a partir de la clase Stopwatch, también podemos usar otros miembros estáticos o compartidos (Shared en VB o static en C#), esos miembros, al estar compartidos, pertenecen a la propia clase, y no a una instancia en particular.
Por un lado tenemos dos campos (se usan como las propiedades) de solo lectura, uno es Frequency, que nos dan información de la frecuencia (en pasos) del temporizador, y el otro es IsHighResolution que devuelve un valor verdadero o falso según se use un temporizador de alta resolución/precisión o no, en el caso de Windows 2000, XP (o superior) seguramente se usará el temporizador de alta resolución.

El método compartido StartNew devuelve una instancia del temporizador y lo inicia, este puede ser el método que usemos para crear nuevos objetos y al mismo tiempo iniciarlos.

 

Un ejemplo de cómo usar la clase Stopwatch (para Visual Basic 2005 y C# 2.0)

Bueno, ya está bien de tanto rollo, veamos cómo usar esta clase. Como es mi costumbre desde hace años, te muestro el código tanto para Visual Basic 2005 como para C# 2.0 (o Visual C# 2005).
Este código funciona en cualquier versión, incluso en las versiones Express, (que si no sabes de que van, te diré que son las versiones gratuitas y totalmente funcionales de Visual Basic 2005 y Visual C# 2005).

Para este ejemplo, en el que calcularemos cuanto tarda el .NET en agregar cadenas usando una clase de tipo String y otra de tipo StringBuilder, usaremos un botón, dos etiquetas y dos cajas de texto, en los TextBox mostraremos el tiempo empleado en cada una de las dos pruebas y el botón lo usaremos para iniciar el proceso de cálculo de tiempo.

El código de ejemplo lo tienes un poco más abajo, aquí está el de Visual Basic y aquí el de C#, pero recuerda que solo es válido para la versión 2005 o superior.

 

¡Que lo temporices bien!

Nos vemos.
Guillermo

 


Código para Visual Basic)El código para Visual Basic 2005 (o superior)

'------------------------------------------------------------------------------
' Prueba de la clase Stopwatch                                      (19/Jul/06)
' para calcular el tiempo que tarda String y StringBuilder
' en agregar un número de cadenas.
'
' ©Guillermo 'guille' Som, 2006
'------------------------------------------------------------------------------
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Imports System.Text
Imports System.Diagnostics

Public Class Form1
    Private temporizador As Stopwatch
    Private Const cuantasCadenas As Integer = 20000

    Private Sub btnCalcular_Click(ByVal sender As Object, ByVal e As EventArgs) _
                     Handles btnCalcular.Click
        btnCalcular.Enabled = False
        btnCalcular.Refresh()
        ' La prueba de StringBuilder (que tarda menos)
        Me.txtStringBuilder.Text = calcularStringBuilder().ToString()
        ' La prueba de String (que tarde un poco más)
        Me.txtString.Text = calcularString().ToString()
        btnCalcular.Enabled = True
        btnCalcular.Refresh()
    End Sub

    Private Function calcularString() As TimeSpan
        Dim s As String = ""
        temporizador = Stopwatch.StartNew()
        For i As Integer = 0 To cuantasCadenas - 1
            s &= "Hola"
        Next
        Return temporizador.Elapsed
    End Function

    Private Function calcularStringBuilder() As TimeSpan
        Dim sb As StringBuilder = New StringBuilder()
        temporizador = Stopwatch.StartNew()
        For i As Integer = 0 To cuantasCadenas - 1
            sb.Append("Hola")
        Next
        Return temporizador.Elapsed
    End Function
End Class

 


Código para C Sharp (C#)El código para C# 2.0 (o superior)

//-----------------------------------------------------------------------------
// Prueba de la clase Stopwatch                                     (19/Jul/06)
// para calcular el tiempo que tarda String y StringBuilder
// en agregar un número de cadenas.
//
// ©Guillermo 'guille' Som, 2006
//-----------------------------------------------------------------------------

using System;
using System.Drawing;
using System.Windows.Forms;

using System.Text;
using System.Diagnostics;

namespace stopwatch_CS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private Stopwatch temporizador;
        private const int cuantasCadenas = 20000;

        private void btnCalcular_Click(object sender, EventArgs e)
        {
            btnCalcular.Enabled = false;
            btnCalcular.Refresh();
            // La prueba de StringBuilder (que tarda menos)
            this.txtStringBuilder.Text = calcularStringBuilder().ToString();
            // La prueba de String (que tarde un poco más)
            this.txtString.Text = calcularString().ToString();
            btnCalcular.Enabled = true;
            btnCalcular.Refresh();
        }

        private TimeSpan calcularString()
        {
            string s = "";
            temporizador = Stopwatch.StartNew();
            for( int i = 0; i < cuantasCadenas; i++ )
            {
                s += "Hola";
            }
            return temporizador.Elapsed;
        }
        private TimeSpan calcularStringBuilder()
        {
            StringBuilder sb = new StringBuilder();
            temporizador = Stopwatch.StartNew();
            for( int i = 0; i < cuantasCadenas; i++ )
            {
                sb.Append("Hola");
            }
            return temporizador.Elapsed;
        }
    }
}

 


Espacios de nombres usados en el código de este artículo:

System.Diagnostics
System.Text
 



Ir al índice principal de el Guille