Python n'est en aucun cas rapide, mais plutôt lent. Par conséquent, Cython essaie d'accélérer en convertissant en C / C ++.
Il est décidé d'être rapide car il est converti en langage inférieur C / C ++ (qui était autrefois un langage de haut niveau, mais maintenant il peut être appelé un langage de bas niveau) et compilé nativement.
Vous pourriez avoir l'impression que ** "Cython est difficile" ** et ** "Cython nécessite des connaissances en C / C ++" **. La réponse est oui" **.
Cependant, la réponse est basée sur l'utilisation complète de Cython. En fait, Cython est conçu pour que vous n'ayez pas besoin d'en savoir beaucoup sur ** C / C ++ pour obtenir suffisamment d'avantages pour un peu d'accélération **.
Cependant, même si vous utilisez Cython à l'aveugle, vous obtiendrez des résultats décevants tels que «pas très rapide» et «très difficile à migrer». Sur la base des points ici, le but de cet article est de permettre aux débutants qui ne sont pas familiarisés avec C / C ++ de prendre et de manger les délicieuses parties de Cython.
Cet article n'explique pas comment installer Cython ou comment écrire setup.py. Si vous le recherchez sur Google, il sortira bientôt, alors veuillez rechercher.
Rendre Cython disponible sur Windows.
Dans cet article, je n'aborderai pas la partie profonde de Cython, mais pour ramasser et manger de la nourriture délicieuse, et je n'expliquerai pas la partie profonde de Cython. Heureusement, si vous voulez connaître la partie profonde de Cython, qui est une traduction japonaise de la documentation de Cython, veuillez vous référer à l'article ci-dessous.
Document Cython (traduction japonaise)
Tout simplement parce que la vitesse de traitement est plus rapide, elle ne devrait pas être accélérée si cela se produit, mais on peut plutôt dire qu'il y a peu d'endroits où l'accélération est efficace avec Cython.
La vitesse d'exécution d'un programme n'est pas uniquement déterminée par la simple vitesse de traitement. La seule chose qui peut être améliorée en améliorant la vitesse de traitement est l'attente (liée au processeur) en raison de nombreux traitements arithmétiques, l'attente d'un accès à la mémoire (liée à la mémoire), l'attente de la lecture des données sur le disque dur, etc. (liées aux E / S), etc. A peu d'effet. Ces problèmes doivent être résolus en améliorant l'algorithme (comme le mémorandum) et le threading / multi-processing.
L'accélération avec Cython est plus facile que le portage vers C / C ++, mais elle reste lourde. Cela n'a souvent pas beaucoup de sens de travailler dur pour accélérer l'ensemble du programme. Il est beaucoup plus efficace d'accélérer une fonction appelée 1000 fois de 1% que d'accélérer une fonction appelée une seule fois de 10%.
Les deux points ci-dessus sont les principes de base et le bon sens de l'accélération. L'important n'est pas d'accélérer l'ensemble du programme, mais de ** comprendre les causes et les emplacements des goulots d'étranglement et de prendre les mesures appropriées **. Paradoxalement, la vitesse de traitement du langage n'est pas si importante, l'amélioration de l'algorithme est plus importante, et le problème de la vitesse d'exécution peut être résolu en améliorant l'algorithme dans la plupart des cas.
Selon la cause du goulot d'étranglement, SWIG ou Numba peuvent être plus appropriés, alors utilisez la bonne personne au bon endroit.
La boucle Python est lente. Cela est dû au fait que diverses vérifications sont effectuées au moment de la boucle en raison de la liberté de stocker différents types dans le tableau. Même si vous utilisez Numpy rapide, tourner le tableau avec pour réduira considérablement la vitesse, et c'est une règle empirique d'éviter le traitement en boucle lors de l'utilisation de Numpy.
En raison du degré de liberté dû au langage typé dynamiquement, la vérification du type de variable est incluse pour chaque opération.
Même une simple opération de a + b
doit passer par la méthode __add__
, ce qui entraîne une surcharge pour chaque opération.
Non limités à Python, les appels de fonction entraînent une surcharge importante. En particulier, les langages typés dynamiquement ont une surcharge plus importante que les langages typés statiquement car la vérification de type est effectuée même lors de l'affectation à la pile.
Jupyter est le meilleur moyen d'implémenter Cython. Cython prend en charge la commande magick de Jupyter, vous pouvez donc facilement l'essayer sur Jupyter.
Sur Jupyter, tapez la commande suivante pour activer Cython.
%load_ext Cython
Expérimentons avec le nombre de Fibonacci que tout le monde aime. Tout d'abord, en Python, créez une fonction Python qui recherche le numéro de Fibonacci.
def py_fib(n):
a, b = 0.0, 1.0
for i in range(n):
a, b = a + b, a
return a
Mesure de vitesse
%timeit py_fib(1000)
>>> 10000 loops, best of 3: 66.9 µs per loop
Ensuite, tapez la commande magique %% cython
au début pour créer une fonction qui a exactement le même contenu que la fonction Python précédente. Encore une fois, le contenu est exactement le même que celui de Python, seul le nom de la fonction est différent.
%%cython
def cy_fib(n):
a, b = 0.0, 1.0
for i in range(n):
a, b = a + b, a
return a
Mesure de vitesse
%timeit cy_fib(1000)
>>> 100000 loops, best of 3: 16 µs per loop
Juste en changeant la fonction Python en Cython, elle est passée de 66,9µs à 16µs, ce qui est plus de 4 fois plus rapide sans rien faire. Cython est assez compatible avec la syntaxe Python, et Cython le convertira en C / C ++ tel quel, à moins qu'il ne s'agisse de code Python trop spécial.
Spécifions le type pour le rendre encore plus rapide.
%%cython
def cy_fib2(int n):
a, b = 0.0, 1.0
for i in range(n):
a, b = a + b, a
return a
Mesure de vitesse
%timeit cy_fib2(1000)
>>> 1000000 loops, best of 3: 1.11 µs per loop
66,9 µs → 1,11 µs, ce qui est 60 fois plus rapide.
L'important ici est que seule la partie `` def cy_fin2 (int n) '' est définie par type, sinon c'est exactement la même chose que la fonction Python.
En fait, Cython fait l'inférence de type et convertit automatiquement les variables ʻaet
b en double type et la variable ʻi
en type int. Même si le code Python est collé tel quel, il se comporte autant que possible à partir du code Python d'origine et est converti en C / C ++ afin de ne pas nuire aux performances.
En Cython, ** le typage aveugle n'a pas beaucoup de sens juste pour réduire la lisibilité **, dans la plupart des cas, vous pouvez obtenir des dizaines de fois plus rapidement en tapant simplement quelques variables.
Si vous tapez %% cython -a
et que vous l'exécutez, Python et C / C ++ ainsi que les lignes qui prennent beaucoup de temps à traiter seront affichés en jaune.
L'utilisation légitime de Cython est de copier et coller le code Python sans y penser, et de taper préférentiellement les lignes jaunes.
En résumé, les parties qui doivent être optimisées pour accélérer ne sont que quelques fonctions dans le code du programme, et seules quelques lignes de ces fonctions devraient être optimisées par Cython. Par conséquent, Cython essaie d'y parvenir facilement tout en conservant la lisibilité.
Cython est souvent considéré comme difficile, mais grâce aux efforts des développeurs Cython, il est presque parfaitement compatible avec Python. Si vous souhaitez accélérer partiellement, vous pouvez obtenir suffisamment d'avantages sans connaître le C / C ++. (Dans 99% des cas, seules quelques accélérations permettront d'atteindre l'objectif)
~~ Cython est très profond, et je profiterai d'une autre occasion pour expliquer comment l'utiliser. ~~
Continuez vers Introduction à Cython sans approfondir -2-.
Recommended Posts