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 :

f1 : 3.559 sec for 10000 iterations
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!