cours_progra/17nov/umons_cpu.py
2022-11-24 09:48:10 +01:00

110 lines
2.8 KiB
Python

"""
Module utilisé à l'UMONS dans le cadre des cours de Programmation et
Algorithmique 1 et Structure de Données 1 pour faciliter le calcul
des temps CPU.
Auteur: Pierre Hauweele et Hadrien Mélot (Université de Mons), 2016
"""
import timeit
import pickle
def __init_timer__(f, *args):
fs = pickle.dumps(f)
argss = pickle.dumps(args)
setup = \
"""
import pickle
import copy
f = pickle.loads(%s)
args = pickle.loads(%s)
""" % (fs, argss)
stmt = 'f(*copy.deepcopy(args))'
return timeit.Timer(stmt, setup)
def __calibrate__(t):
calibrate_test = 0
n = 1
while calibrate_test < 0.1:
n *= 10
calibrate_test = t.timeit(n)
return n, calibrate_test
def cpu_time(f, *args):
""" Retourne un temps CPU exprimé en millisecondes (ms)
- f : fonction ou méthode à tester
- *args : liste d'arguments pour f. Ces arguments ne sont pas
modifiés, même si la fonction f a des effets de bord (ils sont
copiés avant l'exécution).
Exemples :
cputime(math.sqrt, 4)
pour calculer le temps CPU de math.sqrt(4)
cputime(str.upper, 'hello')
pour calculer le temps CPU de 'hello'.upper()
cputime(myfunc, x, y, z)
pour calculer le temps CPU de myfunc(x, y, z)
"""
t = __init_timer__(f, *args)
n, cal_time = __calibrate__(t)
res = min([cal_time] + t.repeat(2, n))
return (res / n) * 1000
def calibrate(f, *args):
""" Retourne un nombre de tests qui rend le calcul du temps CPU
a priori raisonnable.
- f : fonction ou méthode à tester
- *args : liste d'arguments pour f. Ces arguments ne sont pas
modifiés, même si la fonction f a des effets de bord (ils sont
copiés avant l'exécution).
Le nombre de tests retourné est une puissance de 10 (au minimum 10). Il
sera d'autant plus grand si la fonction semble rapide.
"""
t = __init_timer__(f, *args)
n, cal_time = __calibrate__(t)
return n
def cpu_time_without_copy(f, *args):
""" Retourne un temps CPU exprimé en millisecondes (ms)
- f : fonction ou méthode à tester
- *args : liste d'arguments pour f.
Cette version ne copie pas les arguments:
il ne faut donc l'utiliser qu'avec des fonctions
sans effet de bord !
"""
fs = pickle.dumps(f)
argss = pickle.dumps(args)
setup = \
"""
import pickle
f = pickle.loads(%s)
args = pickle.loads(%s)
""" % (fs, argss)
stmt = 'f(*args)'
t = timeit.Timer(stmt, setup)
calibrate_test = 0
n = 1
while calibrate_test < 0.1:
n *= 10
calibrate_test = t.timeit(n)
res = min([calibrate_test] + t.repeat(2, n))
return (res / n) * 1000