Προγραμματισμός

Τι είναι το Cython; Python με ταχύτητα C

Η Python έχει τη φήμη ότι είναι μία από τις πιο βολικές, πλούσια εξοπλισμένες και εντελώς χρήσιμες γλώσσες προγραμματισμού. Ταχύτητα εκτέλεσης; Οχι τόσο πολύ.

Μπείτε στο Cython. Η γλώσσα Cython είναι ένα υπερσύνολο της Python που μεταγλωττίζεται στο C, αποδίδοντας βελτιώσεις απόδοσης που μπορεί να κυμαίνονται από λίγα τοις εκατό έως αρκετές τάξεις μεγέθους, ανάλογα με την υπό εξέταση εργασία. Για εργασίες που συνδέονται με τους εγγενείς τύπους αντικειμένων της Python, οι ταχύτητες δεν θα είναι μεγάλες. Αλλά για αριθμητικές πράξεις ή για οποιεσδήποτε πράξεις που δεν περιλαμβάνουν εσωτερικά της Python, τα κέρδη μπορεί να είναι τεράστια.

Με το Cython, μπορείτε να παρακάμψετε πολλούς από τους φυσικούς περιορισμούς της Python ή να τους ξεπεράσετε εντελώς - χωρίς να πρέπει να εγκαταλείψετε την ευκολία και την ευκολία της Python. Σε αυτό το άρθρο, θα εξετάσουμε τις βασικές έννοιες πίσω από το Cython και θα δημιουργήσουμε μια απλή εφαρμογή Python που χρησιμοποιεί το Cython για να επιταχύνει μία από τις λειτουργίες της.

Σχετικό βίντεο: Χρήση του Cython για επιτάχυνση του Python

Μεταγλώττιση Python σε C

Ο κώδικας Python μπορεί να πραγματοποιεί κλήσεις απευθείας σε μονάδες C. Αυτές οι ενότητες C μπορούν να είναι είτε γενικές βιβλιοθήκες C είτε βιβλιοθήκες που έχουν κατασκευαστεί ειδικά για να συνεργάζονται με την Python. Το Cython δημιουργεί το δεύτερο είδος ενότητας: βιβλιοθήκες C που μιλούν με τα εσωτερικά της Python και μπορούν να συνδυαστούν με τον υπάρχοντα κώδικα Python.

Ο κώδικας Cython μοιάζει πολύ με τον κώδικα Python, από τη σχεδίαση. Εάν τροφοδοτήσετε στον μεταγλωττιστή Cython ένα πρόγραμμα Python (υποστηρίζονται και τα Python 2.x και Python 3.x), η Cython θα το αποδεχτεί ως έχει, αλλά καμία από τις εγγενείς επιταχύνσεις της Cython δεν θα τεθεί σε λειτουργία. Αλλά αν διακοσμήσετε τον κώδικα Python με σχολιασμούς τύπου στην ειδική σύνταξη της Cython, η Cython θα μπορεί να αντικαταστήσει τα γρήγορα ισοδύναμα C για αργά αντικείμενα Python.

Σημειώστε ότι η προσέγγιση της Cython είναισταδιακή. Αυτό σημαίνει ότι ένας προγραμματιστής μπορεί να ξεκινήσει με έναυπάρχον Εφαρμογή Python και επιτάχυνση κάνοντας άμεσες αλλαγές στον κώδικα, αντί να ξαναγράψετε ολόκληρη την εφαρμογή από την αρχή.

Αυτή η προσέγγιση αντιστοιχεί στη φύση των ζητημάτων απόδοσης λογισμικού γενικά. Στα περισσότερα προγράμματα, η συντριπτική πλειοψηφία του κώδικα υψηλής έντασης CPU συγκεντρώνεται σε μερικά καυτά σημεία - μια έκδοση της αρχής Pareto, επίσης γνωστή ως κανόνας "80/20". Επομένως, το μεγαλύτερο μέρος του κώδικα σε μια εφαρμογή Python δεν χρειάζεται να βελτιστοποιηθεί για την απόδοση, μόνο μερικά κρίσιμα κομμάτια. Μπορείτε να μεταφράσετε σταδιακά αυτά τα καυτά σημεία στο Cython και, συνεπώς, να αποκτήσετε τα κέρδη απόδοσης που χρειάζεστε όπου έχει μεγαλύτερη σημασία. Το υπόλοιπο πρόγραμμα μπορεί να παραμείνει στο Python για την ευκολία των προγραμματιστών.

Πώς να χρησιμοποιήσετε το Cython

Εξετάστε τον ακόλουθο κώδικα, από τον φάκελο της Cython:

def f (x):

επιστροφή x ** 2-x

def integrate_f (a, b, N):

s = 0

dx = (b-a) / Ν

για i στην περιοχή (N):

s + = f (a + i * dx)

επιστροφή s * dx

Αυτό είναι ένα παράδειγμα παιχνιδιού, μια μη αποδοτική εφαρμογή μιας ολοκληρωμένης λειτουργίας. Ως καθαρός κώδικας Python, είναι αργός, επειδή το Python πρέπει να μετατρέπεται μπρος-πίσω μεταξύ αριθμητικών τύπων εγγενών μηχανών και των δικών του τύπων εσωτερικών αντικειμένων.

Τώρα εξετάστε την έκδοση Cython του ίδιου κώδικα, με υπογραμμισμένες τις προσθήκες της Cython:

 cdef double f (διπλό x):

επιστροφή x ** 2-x

def integrate_f (double a, double b, int N):

cdef int i

cdef double s, x, dx

s = 0

dx = (b-a) / Ν

για i στην περιοχή (N):

s + = f (a + i * dx)

επιστροφή s * dx

Εάν δηλώσουμε ρητά τους τύπους μεταβλητών, τόσο για τις παραμέτρους της συνάρτησης όσο και για τις μεταβλητές που χρησιμοποιούνται στο σώμα της συνάρτησης (διπλό, int, κ.λπ.), η Cython θα τα μεταφράσει όλα σε C. Μπορούμε επίσης να χρησιμοποιήσουμε το cdef λέξη-κλειδί για τον καθορισμό συναρτήσεων που υλοποιούνται κυρίως σε C για επιπλέον ταχύτητα, αν και αυτές οι συναρτήσεις μπορούν να κληθούν μόνο από άλλες συναρτήσεις Cython και όχι από σενάρια Python. (Στο παραπάνω παράδειγμα, μόνο ολοκλήρωση_f μπορεί να κληθεί από άλλο σενάριο Python.)

Σημειώστε πόσο λίγο είναι το πραγματικό μαςκώδικας άλλαξε. Το μόνο που έχουμε κάνει είναι να προσθέσουμε δηλώσεις τύπων στον υπάρχοντα κώδικα για να έχουμε σημαντική αύξηση της απόδοσης.

Πλεονεκτήματα Cython

Εκτός από τη δυνατότητα επιτάχυνσης του κώδικα που έχετε ήδη γράψει, η Cython προσφέρει πολλά άλλα πλεονεκτήματα:

Η εργασία με εξωτερικές βιβλιοθήκες Γ μπορεί να είναι ταχύτερη

Πακέτα Python όπως το NumPy τυλίγουν βιβλιοθήκες C σε διεπαφές Python για να διευκολύνουν την εργασία τους. Ωστόσο, η μετάβαση μεταξύ Python και C μέσω αυτών των περιτυλίξεων μπορεί να επιβραδύνει τα πράγματα. Το Cython σάς επιτρέπει να μιλάτε απευθείας στις υποκείμενες βιβλιοθήκες, χωρίς τον Python να παρεμποδίζει. (Υποστηρίζονται επίσης βιβλιοθήκες C ++.)

Μπορείτε να χρησιμοποιήσετε τη διαχείριση μνήμης C και Python

Εάν χρησιμοποιείτε αντικείμενα Python, διαχειρίζονται μνήμη και συλλέγονται σκουπίδια όπως και στην κανονική Python. Αλλά αν θέλετε να δημιουργήσετε και να διαχειριστείτε τις δικές σας δομές C-level και να χρησιμοποιήσετε malloc/Ελεύθερος για να συνεργαστείτε μαζί τους, μπορείτε να το κάνετε. Απλά θυμηθείτε να καθαρίσετε τον εαυτό σας.

Μπορείτε να επιλέξετε ασφάλεια ή ταχύτητα όπως απαιτείται

Το Cython εκτελεί αυτόματα ελέγχους χρόνου εκτέλεσης για κοινά προβλήματα που εμφανίζονται στο C, όπως πρόσβαση εκτός ορίου σε μια συστοιχία, μέσω διακοσμητών και οδηγιών μεταγλωττιστή (π.χ. @boundscheck (Λάθος)). Κατά συνέπεια, ο κώδικας C που δημιουργείται από τη Cython είναι πολύ ασφαλέστερος από προεπιλογή από ότι ο χειροκίνητος κώδικας C, αν και ενδεχομένως στο κόστος της πρώτης απόδοσης.

Εάν είστε βέβαιοι ότι δεν θα χρειαστείτε αυτούς τους ελέγχους κατά το χρόνο εκτέλεσης, μπορείτε να τους απενεργοποιήσετε για πρόσθετα κέρδη ταχύτητας, είτε σε ολόκληρη τη μονάδα είτε μόνο σε επιλεγμένες λειτουργίες.

Το Cython σας επιτρέπει επίσης να έχετε εγγενή πρόσβαση σε δομές Python που χρησιμοποιούν το πρωτόκολλο buffer για άμεση πρόσβαση σε δεδομένα που είναι αποθηκευμένα στη μνήμη (χωρίς ενδιάμεση αντιγραφή). Οι προβολές μνήμης της Cython σάς επιτρέπουν να εργάζεστε με αυτές τις δομές με υψηλή ταχύτητα και με το επίπεδο ασφάλειας που είναι κατάλληλο για την εργασία. Για παράδειγμα, τα ακατέργαστα δεδομένα που βρίσκονται κάτω από μια συμβολοσειρά Python μπορούν να διαβαστούν με αυτόν τον τρόπο (γρήγορα) χωρίς να χρειάζεται να περάσουν από το χρόνο εκτέλεσης του Python (αργό).

Ο κώδικας Cython C μπορεί να επωφεληθεί από την κυκλοφορία του GIL

Το Global Interpreter Lock της Python, ή το GIL, συγχρονίζει τα νήματα εντός του διερμηνέα, προστατεύοντας την πρόσβαση σε αντικείμενα της Python και διαχειρίζοντας τους πόρους για πόρους. Ωστόσο, το GIL έχει επικριθεί ευρέως ως εμπόδιο για την Python με καλύτερη απόδοση, ειδικά σε συστήματα πολλαπλών πυρήνων.

Εάν έχετε μια ενότητα κώδικα που δεν κάνει καμία αναφορά σε αντικείμενα Python και εκτελεί μια μακροχρόνια λειτουργία, μπορείτε να το επισημάνετε με τομε nogil: οδηγία για να το επιτρέψει να τρέξει χωρίς το GIL. Αυτό ελευθερώνει τον διερμηνέα Python για να κάνει άλλα πράγματα και επιτρέπει στον κώδικα Cython να κάνει χρήση πολλαπλών πυρήνων (με επιπλέον εργασία).

Η Cython μπορεί να χρησιμοποιήσει σύνταξη υπαινιγμού τύπου Python

Η Python έχει μια σύνταξη τύπου-υπαινιγμού που χρησιμοποιείται κυρίως από linters και ελεγκτές κώδικα, και όχι από τον διερμηνέα CPython. Η Cython έχει τη δική της προσαρμοσμένη σύνταξη για διακοσμήσεις κώδικα, αλλά με τις πρόσφατες αναθεωρήσεις του Cython μπορείτε να χρησιμοποιήσετε τη σύνταξη τύπου Python για να παρέχετε βασικές συμβουλές τύπου στη Cython.

Το Cython μπορεί να χρησιμοποιηθεί για να αποκρύψει τον ευαίσθητο κώδικα Python

Οι μονάδες Python είναι ασήμαντα εύκολο να αποσυντεθούν και να ελεγχθούν, αλλά τα μεταγλωττισμένα δυαδικά αρχεία δεν είναι. Όταν διανέμετε μια εφαρμογή Python σε τελικούς χρήστες, εάν θέλετε να προστατεύσετε ορισμένες από τις ενότητες της από περιστασιακή κατασκοπεία, μπορείτε να το κάνετε με τη σύνταξη τους με το Cython. Σημειώστε, ωστόσο, αυτό είναι παρενέργεια των δυνατοτήτων της Cython και όχι μία από τις προβλεπόμενες λειτουργίες της.

Περιορισμοί Cython

Λάβετε υπόψη ότι το Cython δεν είναι ένα μαγικό ραβδί. Δεν μετατρέπει αυτόματα κάθε εμφάνιση κώδικα pyy Python σε γρήγορο κώδικα C. Για να αξιοποιήσετε στο έπακρο το Cython, πρέπει να το χρησιμοποιήσετε με σύνεση - και να κατανοήσετε τους περιορισμούς του:

Λίγη επιτάχυνση για συμβατικό κώδικα Python

Όταν η Cython συναντά τον κώδικα Python δεν μπορεί να μεταφραστεί πλήρως σε C, μετατρέπει αυτόν τον κώδικα σε μια σειρά κλήσεων C στα εσωτερικά της Python. Αυτό ισοδυναμεί με την απομάκρυνση του διερμηνέα της Python από τον βρόχο εκτέλεσης, ο οποίος δίνει στον κώδικα μια μέτρια ταχύτητα 15 έως 20% από προεπιλογή. Σημειώστε ότι αυτό είναι ένα σενάριο με τις καλύτερες περιπτώσεις. Σε ορισμένες περιπτώσεις, ενδέχεται να μην βλέπετε καμία βελτίωση της απόδοσης ή ακόμη και μια υποβάθμιση της απόδοσης.

Μικρή επιτάχυνση για εγγενείς δομές δεδομένων Python

Η Python παρέχει πολλές δομές δεδομένων - συμβολοσειρές, λίστες, πλειάδες, λεξικά κ.ο.κ. Είναι εξαιρετικά βολικά για προγραμματιστές και διαθέτουν τη δική τους αυτόματη διαχείριση μνήμης. Αλλά είναι πιο αργά από το καθαρό C.

Το Cython σάς επιτρέπει να συνεχίσετε να χρησιμοποιείτε όλες τις δομές δεδομένων Python, αν και χωρίς μεγάλη επιτάχυνση. Αυτό συμβαίνει και πάλι, επειδή η Cython καλεί απλά τα C APIs στο Python runtime που δημιουργούν και χειρίζονται αυτά τα αντικείμενα. Έτσι, οι δομές δεδομένων Python συμπεριφέρονται σαν τον κώδικα Python βελτιστοποιημένος με Cython γενικά: Μερικές φορές παίρνετε μια ώθηση, αλλά μόνο λίγο. Για καλύτερα αποτελέσματα, χρησιμοποιήστε μεταβλητές και δομές C. Τα καλά νέα είναι ότι η Cython διευκολύνει τη συνεργασία μαζί τους.

Ο κωδικός Cython εκτελείται ταχύτερα όταν το "καθαρό C"

Εάν έχετε μια συνάρτηση στο C με την ένδειξη cdef λέξη-κλειδί, με όλες τις μεταβλητές και τις ενσωματωμένες κλήσεις σε άλλα πράγματα που είναι καθαρά C, θα τρέχει όσο πιο γρήγορα μπορεί να φτάσει το C. Αλλά αν αυτή η συνάρτηση αναφέρεται σε οποιονδήποτε εγγενή κώδικα Python, όπως μια δομή δεδομένων Python ή μια κλήση σε ένα εσωτερικό API Python, αυτή η κλήση θα είναι ένα εμπόδιο απόδοσης.

Ευτυχώς, η Cython παρέχει έναν τρόπο εντοπισμού αυτών των σημείων συμφόρησης: μια αναφορά πηγαίου κώδικα που δείχνει με μια ματιά ποια μέρη της εφαρμογής Cython είναι καθαρά C και ποια μέρη αλληλεπιδρούν με την Python. Όσο καλύτερα βελτιστοποιηθεί η εφαρμογή, τόσο λιγότερη αλληλεπίδραση θα υπάρχει με την Python.

Cython NumPy

Το Cython βελτιώνει τη χρήση βιβλιοθηκών αριθμού τρίτων με βάση το C, όπως το NumPy. Επειδή ο κώδικας Cython μεταγλωττίζεται στο C, μπορεί να αλληλεπιδράσει απευθείας με αυτές τις βιβλιοθήκες και να αφαιρέσει τα σημεία συμφόρησης της Python.

Αλλά το NumPy, ιδιαίτερα, λειτουργεί καλά με τη Cython. Το Cython έχει εγγενή υποστήριξη για συγκεκριμένες κατασκευές στο NumPy και παρέχει γρήγορη πρόσβαση σε συστοιχίες NumPy. Και η ίδια γνωστή σύνταξη NumPy που θα χρησιμοποιούσατε σε ένα συμβατικό σενάριο Python μπορεί να χρησιμοποιηθεί στο Cython ως έχει.

Ωστόσο, εάν θέλετε να δημιουργήσετε τις πλησιέστερες δυνατές συνδέσεις μεταξύ Cython και NumPy, θα πρέπει να διακοσμήσετε περαιτέρω τον κώδικα με την προσαρμοσμένη σύνταξη της Cython. οcimport Η δήλωση, για παράδειγμα, επιτρέπει στον κώδικα Cython να βλέπει κατασκευές επιπέδου C σε βιβλιοθήκες κατά το χρόνο μεταγλώττισης για τις ταχύτερες δυνατές συνδέσεις.

Δεδομένου ότι το NumPy χρησιμοποιείται τόσο ευρέως, η Cython υποστηρίζει το NumPy "εκτός κουτιού". Εάν έχετε εγκαταστήσει το NumPy, μπορείτε απλώς να το δηλώσετεcimport numpy στον κωδικό σας και, στη συνέχεια, προσθέστε περαιτέρω διακόσμηση για να χρησιμοποιήσετε τις εκτεθειμένες λειτουργίες.

Προφίλ και απόδοση Cython

Παίρνετε την καλύτερη απόδοση από οποιοδήποτε κομμάτι κώδικα σχεδιάζοντας το και βλέποντας από πρώτο χέρι πού βρίσκονται τα σημεία συμφόρησης. Το Cython παρέχει άγκιστρα για τη μονάδα cProfile της Python, οπότε μπορείτε να χρησιμοποιήσετε τα εργαλεία δημιουργίας προφίλ της Python, όπως το cProfile, για να δείτε την απόδοση του κώδικα Cython.

Σας βοηθά να θυμάστε σε όλες τις περιπτώσεις ότι η Cython δεν είναι μαγική - ότι εξακολουθούν να ισχύουν λογικές πρακτικές απόδοσης στον πραγματικό κόσμο. Όσο λιγότερο κάνετε εναλλαγή μεταξύ Python και Cython, τόσο πιο γρήγορα θα εκτελείται η εφαρμογή σας.

Για παράδειγμα, εάν έχετε μια συλλογή αντικειμένων που θέλετε να επεξεργαστείτε στο Cython, μην επαναλάβετε την επίσκεψή της στο Python και επικαλέστε μια λειτουργία Cython σε κάθε βήμα. Πέρασμα ολόκληρη η συλλογή στη μονάδα Cython και πραγματοποιήστε επανάληψη εκεί. Αυτή η τεχνική χρησιμοποιείται συχνά σε βιβλιοθήκες που διαχειρίζονται δεδομένα, οπότε είναι καλό μοντέλο να μιμηθείτε στον δικό σας κώδικα.

Χρησιμοποιούμε το Python επειδή παρέχει ευκολία προγραμματιστή και επιτρέπει γρήγορη ανάπτυξη. Μερικές φορές αυτή η παραγωγικότητα προγραμματιστή έρχεται στο κόστος της απόδοσης. Με το Cython, λίγη επιπλέον προσπάθεια μπορεί να σας δώσει το καλύτερο και των δύο κόσμων.

Διαβάστε περισσότερα για Python

  • Τι είναι το Python; Ισχυρός, διαισθητικός προγραμματισμός
  • Τι είναι το PyPy; Γρηγορότερη Python χωρίς πόνο
  • Τι είναι το Cython; Python με ταχύτητα C
  • Εκμάθηση Cython: Πώς να επιταχύνετε το Python
  • Πώς να εγκαταστήσετε το Python με τον έξυπνο τρόπο
  • Οι καλύτερες νέες δυνατότητες στο Python 3.8
  • Καλύτερη διαχείριση έργου Python με την Ποίηση
  • Virtualenv και venv: Εξηγήθηκαν εικονικά περιβάλλοντα Python
  • Το Python virtualenv και το venv κάνουν και δεν πρέπει
  • Η εξήγηση και οι υποεπεξεργασίες Python εξηγούνται
  • Πώς να χρησιμοποιήσετε το πρόγραμμα εντοπισμού σφαλμάτων Python
  • Πώς να χρησιμοποιήσετε το χρονοδιάγραμμα για τον προφίλ κώδικα Python
  • Πώς να χρησιμοποιήσετε το cProfile για να προβάλετε τον κώδικα Python
  • Ξεκινήστε με το async στο Python
  • Πώς να χρησιμοποιήσετε το asyncio στο Python
  • Πώς να μετατρέψετε το Python σε JavaScript (και να επιστρέψετε ξανά)
  • Python 2 EOL: Πώς να επιβιώσετε στο τέλος του Python 2
  • 12 Pythons για κάθε ανάγκη προγραμματισμού
  • 24 βιβλιοθήκες Python για κάθε προγραμματιστή Python
  • 7 γλυκά IDE Python που ίσως έχετε χάσει
  • 3 μεγάλες αδυναμίες της Python - και οι λύσεις τους
  • Συγκρίθηκαν 13 πλαίσια Ιστού Python
  • 4 Πλαίσια δοκιμής Python για τη συντριβή των σφαλμάτων σας
  • 6 υπέροχες νέες δυνατότητες Python που δεν θέλετε να χάσετε
  • 5 Διανομές Python για την εξάσκηση της μηχανικής μάθησης
  • 8 υπέροχες βιβλιοθήκες Python για επεξεργασία φυσικής γλώσσας