Pourquoi les tableaux de Python sont-ils lents?


Answers

Pour ajouter à l'excellente réponse de Tim Peters, les tableaux implémentent le protocole tampon , contrairement aux listes. Cela signifie que, si vous écrivez une extension C (ou l'équivalent moral, comme l'écriture d'un module Cython ), alors vous pouvez accéder et travailler avec les éléments d'un tableau beaucoup plus rapidement que tout ce que Python peut faire. Cela vous donnera des améliorations de vitesse considérables, peut-être bien au-dessus d'un ordre de grandeur. Cependant, il a un certain nombre de inconvénients:

  1. Vous êtes maintenant dans l'écriture de C au lieu de Python. Cython est un moyen d'améliorer cela, mais il n'élimine pas beaucoup de différences fondamentales entre les langues; vous devez être familier avec la sémantique C et comprendre ce qu'il fait.
  2. L'API C de PyPy fonctionne dans une certaine mesure , mais n'est pas très rapide. Si vous ciblez PyPy, vous devez probablement écrire du code simple avec des listes régulières, puis laisser JITter l'optimiser pour vous.
  3. Les extensions C sont plus difficiles à distribuer que le code Python pur car elles doivent être compilées. La compilation a tendance à être dépendante de l'architecture et du système d'exploitation, vous devrez donc vous assurer que vous compilez pour votre plate-forme cible.

Aller directement aux extensions C peut utiliser un marteau pour frapper une mouche, selon votre cas d'utilisation. Vous devriez d'abord enquêter sur NumPy et voir si elle est assez puissante pour faire les maths que vous essayez de faire. Il sera aussi beaucoup plus rapide que le Python natif, s'il est utilisé correctement.

Question

Je m'attendais à ce que array.array soit plus rapide que les listes, car les tableaux semblent être sans boîte.

Cependant, j'obtiens le résultat suivant:

In [1]: import array

In [2]: L = list(range(100000000))

In [3]: A = array.array('l', range(100000000))

In [4]: %timeit sum(L)
1 loop, best of 3: 667 ms per loop

In [5]: %timeit sum(A)
1 loop, best of 3: 1.41 s per loop

In [6]: %timeit sum(L)
1 loop, best of 3: 627 ms per loop

In [7]: %timeit sum(A)
1 loop, best of 3: 1.39 s per loop

Quelle pourrait être la cause d'une telle différence?




Links