Ir al contenido principal

Medición de tiempo en Python

Buenas a todos, ayer me llegó un tweet en el que alguien necesitaba trabajar con conjuntos (sets) en PYTHON.

Esta persona se encontró con diversas opiniones sobre como era más correcto trabajar con los conjuntos, encontrándose con que la discusión derivó a mediciones tiempos y ordenes de eficiencia (como de lento es cada método).

Y aquí es donde me di cuenta que siempre elijo el mejor, pero no entro a cronometrar el algoritmo (en cuanto a las funciones a utilizar, si estás utilizando python3 deberías considerar esta entrada: https://jesusenlanet.blogspot.com/2018/08/python3-stop-measuring-time-with.html).

Así, he estado buscando las diferentes formas de medir tiempos, y me he encontrado con varias formas, diré cuales son y por que las descarto:

- Medir el tiempo "a mocho" dentro del código y ensuciándolo
Descartado radicalmente por ser poco elegante y propenso a que se meta la pata.

- Uso de hilos con thread.
Descartado debido a que según he leído, el modulo thread es opcional y dependiente de la plataforma, pudiendo tener que recompilar el interprete en algunas ocasiones.

Como puede que le de problemas de cabeza a alguien, descartado.

- Uso de un decorador : D
Si queremos que todo esto quede más bonito y elegante, y a la vez sea muy reutilizable, lo suyo es usar un decorador, te dejará el código tan bonito que hasta la SGAE lo considerará obra de arte.



USO DE DECORADORES EN MEDICIÓN DE TIEMPOS

Un decorador es una función D, que admite como parámetro una función F, y retorna una función R, que será la función F decorada por D.

R = D(F)

Y diréis, ¿esto que es lo que es?, ¿para que sirve?, ¿no estábamos programando?

Ejemplo con código:

def decorador(funcionF):
    def funcionR(*args):
        print "Se va a ejecutar %s" % f.__name__
        f(*args)
        print "Se ha ejecutado %s" % f.__name__
    return inner


// funcionQueQuieroDecorar es nuestra funcionF
// @decorador indica que funcionQueQuieroDecorar debe ser decorada con decorador
// A esta forma de usar los decoradores se le llama SAL SINTÁCTICA
// Así cuando llamemos a funcionQueQuieroDecorar en realidad se ejecutará el código de funcionR

@decorador
def funcionQueQuieroDecorar():
    print "Esta es la funcion que quiero decorar"

 
funcionQueQuieroDecorar()

Esto es un decorador muy simple, si queremos realizar ahora la medición de tiempos, el decorador debería de tener un aspecto tal que este:

import time

def decorador(funcionF):
    def funcionR(*arg):
        t1 = time.clock()
        res = funcionF(*arg)
        t2 = time.clock()
        print '%s tarda %0.5f ms' % (funcionF.__name__, (t2-t1)*1000.0)
        return res
    return funcionR
 
@decorador
def funcionF():
 print "Esta es la funcion que quiero decorar."

funcionF()

La idea es envolver la función que queremos ejecutar con las herramientas de medición mediante un decorador.

Se está usando el método clock() en vez de time() por cuestiones de arquitectura y precisión. En general parece ser que el método clock es más exacto que time, aunque dejo como práctica que jugueteéis con el decorador para refinarlo más.

Se podría hacer por ejemplo que se detectara la arquitectura y llamase al método más apropiado.

Actualización: Si utilizas python3 deberías considerar este artículo: https://jesusenlanet.blogspot.com/2018/08/python3-stop-measuring-time-with.html

Un saludo.

Comentarios

Entradas populares de este blog

Join o producto cartesiano de dos tablas en EXCEL 2007

Hace unos dias inicie mi ocupacion como becario de informatica en la facultad de humanidades y ciencias de la educacion de la UJAEN. Y como no, no han tardado en surgir los problemas. Supongamos que tenemos dos tablas, y queremos hacer una tabla que tenga datos de estas dos tablas, segun un criterio , y es que solo pueden aparecer ciertas filas, mas exactamente aquellas donde coincida cierto campo, en este ejemplo, el codigo de la asignatura. Si queremos realizar el join o producto cartesiano tal y como lo hariamos en una base de datos, parece ser que si no estamos trabajando con una bbdd sino con Excel, la cosa se complica un poco. Para "multiplicar tablas" en excel, primero vamos a hacer una cosa, cada tabla la vamos a guardar en hojas separadas, en nuestro caso, una tabla la guardamos en Hoja1 , y la otra en Hoja2 Ahora, nos situamos en la hoja donde queramos que aparezca el producto cartesiano de nuestras dos tablas, nos vamos a la ficha DATOS . Veremos que h

Descargar código fuente desde Google App Engine

Estaba desarrollando una aplicación en google app engine, cuando un día, al llegar al trabajo (hoy), me doy cuenta que no tengo acceso a mi versión de desarrollo. Como la ultima versión que estaba desarrollando, justo la noche de antes la había subido a google app engine, pues me dije: "Ya esta, me conecto y me descargo el código fuente" ERROR 404 // SOLUCIÓN A IDEA MÁGICA NO ENCONTRADA Tras buscar por google, observo que hay muchas voces que dicen que no te puedes descargar el código fuente, que google no deja disponible ninguna API para descargarte tu codigo, ... ¡Pero como va a ser así!, desde appengine, te dicen que se puede hacer, lo que no está tan claro es como hacerlo. Pues estos son los pasos para poder hacerlo: Crear un directorio vacío para poder descargar en el nuestra aplicación. Abrir la línea de comandos, y cambiarnos al directorio de google app engine: cd C:\Archivos de Programa\Google\google_appengine\ Ejecutar el siguiente comando para descar

Clases abstractas con python

¿Como se crean clases abstractas con python?. Voy a explicar cual es la forma correcta de definir una clase abstracta y heredar de ella. El procedimiento general es: Definir una clase abstracta utilizando una metaclase. Definir la subclase de la clase abstracta (sin herencia). Registrar esta última clase como subclase de la clase abstracta. Tomemos como ejemplo el siguiente código: from abc import ABCMeta, abstractmethod class AbstractFoo:     __metaclass__ = ABCMeta          @abstractmethod     def bar(self):         pass     @classmethod     def __subclasshook__(cls, C):         return NotImplemented class Foo(object):     def bar(self):         print "hola" AbstractFoo.register(Foo)  Lo primero que hacemos es importar del módulo abc la clase ABCMeta y el decorador abstractmethod . La clase ABCMeta es la metaclase que utilizamos para definir las clases abstractas, nos aporta una serie de funcionalidades. Una vez hemos asignada la metacl