Bien souvent, nous faisons les choses par habitude. Lorsque nous devenons confortables, nous avons tendance à rester dans notre zone de confort et à toujours faire les choses de la même façon. C’est exactement la même chose en programmation. Jusqu’au jour où le doute nous frappe. Est-ce qu’il y aurait un moyen plus rapide d’effectuer cette tâche? Lorsque ce jour viendra (si la dite tâche est en Python), le module timeit
pourra vous aider! Bien sûr, il existe d’autres moyens de comparer des temps d’exécution en Python. J’utilise d’ailleurs très souvent le module time. J’initie un temps t0, t0 = time.time()
, j’exécute ma tâche et j’imprime le temps écoulé, print time.time()-t0
.
Le module timeit
a l’avantage d’être simple et de pouvoir être appelé de la ligne de commande.
En me référant à l’exemple de Xiaonuo Gantan sur PythonCentral, j’ai rapidement été capable de voir que la compréhension de listes est encore la méthode la plus rapide pour remplacer un caractère dans des chaînes de caractères.
Voici le contexte : j’utilise un dataframe pandas avec des noms de colonnes vraiment chaotiques. Je veux donc remplacer tous les caractères spéciaux rencontrés puisque je dois par la suite convertir mon dataframe pandas en dataframe R. J’ai toujours utilisé la compréhension de listes pour faire ça, mais j’ai récemment vu la méthode map
de pandas. Je me suis donc demandé si j’utilisais la méthode la plus rapide.
Voici le code du test que j’ai effectué :
import re
def wrapper(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
def f1 (l) :
# Utilisation du module d'expressions régulières
return[re.sub(r'=', 'eq', x, flags=re.IGNORECASE) for x in list(l)]
def f2 (l) :
# Utilisation de la fonction map et d'une condition
return l.map(lambda x: x.replace('=', 'eq') if isinstance(x, (str, unicode)) else x)
def f3 (l) :
# Utilisation de la fonction map
return l.map(lambda x: x.replace('=', 'eq'))
def f4 (l) :
# Utilisation de compréhension de listes
return [x.replace('=', 'eq') for x in list(l)]
def f5 (l) :
# Utilisation d'une boucle
c = []
for e in l :
c.append(e.replace('=','eq'))
return c
fs = [f1,f2,f3,f4,f5]
for f in fs :
wrapped = wrapper(f,df.columns)
print '%s : %.3f sec for 10000 iterations ' % (f.func_name, timeit.timeit(wrapped, number=10000))
Et voici la sortie :
f2 : 0.927 sec for 10000 iterations
f3 : 0.607 sec for 10000 iterations
f4 : 0.358 sec for 10000 iterations
f5 : 0.478 sec for 10000 iterations
La grande gagnante… f4!
Laisser un commentaire