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

Πώς να χρησιμοποιήσετε το cProfile για να προβάλετε τον κώδικα Python

Η Python μπορεί να μην είναι η πιο γρήγορη γλώσσα, αλλά είναι αρκετά γρήγορη. Και το Python είναι ιδανικό όταν ο χρόνος προγραμματιστή έχει μεγαλύτερη σημασία από τον χρόνο CPU.

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

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

ο cΠροφίλ Η ενότητα συγκεντρώνει στατιστικά στοιχεία σχετικά με τον χρόνο εκτέλεσης ενός προγράμματος Python. Μπορεί να αναφέρει οτιδήποτε από ολόκληρη την εφαρμογή σε μια μόνο δήλωση ή έκφραση.

Εδώ είναι ένα παράδειγμα παιχνιδιού για το πώς να το χρησιμοποιήσετε cΠροφίλ:

def add (x, y): x + = str (y) return x def add_2 (x, y): if y% 20000 == 0: z = [] για q στο εύρος (0,400000): z.append ( q) def main (): a = [] για n in range (0,200000): add (a, n) add_2 (a, n) if __name__ == '__main__': import cProfile cProfile.run ('main ( ) ") 

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

Εκτελέστε το παραπάνω παράδειγμα και θα σας υποδεχτεί με την ακόλουθη έξοδο:

Αυτό που εμφανίζεται εδώ είναι μια λίστα με όλες τις κλήσεις λειτουργιών που πραγματοποιούνται από το πρόγραμμα, καθώς και στατιστικά στοιχεία για κάθε μία:

  • Στην κορυφή (πρώτη γραμμή με μπλε χρώμα), βλέπουμε τον συνολικό αριθμό κλήσεων που πραγματοποιήθηκαν στο πρόγραμμα προφίλ και τον συνολικό χρόνο εκτέλεσης. Μπορεί επίσης να δείτε μια φιγούρα για «πρωτόγονες κλήσεις» μη αναδρομική κλήσεις ή κλήσεις που πραγματοποιούνται απευθείας σε μια συνάρτηση που με τη σειρά τους δεν καλούν στη συνέχεια στη στοίβα κλήσεων.
  • ncalls: Αριθμός κλήσεων που πραγματοποιήθηκαν. Εάν δείτε δύο αριθμούς διαχωρισμένους με κάθετο, ο δεύτερος αριθμός είναι ο αριθμός των πρωτόγονων κλήσεων για αυτήν τη λειτουργία.
  • τελική ώρα: Συνολικός χρόνος που αφιερώνεται στη συνάρτηση, δεν συμπεριλαμβανομένων κλήσεων σε άλλες λειτουργίες.
  • υπερβάλλω: Μέσος χρόνος ανά κλήση για τελική ώρα, προέρχεται από τη λήψη τελική ώρα και διαιρώντας το με ncalls.
  • χάλια: Συνολικός χρόνος που αφιερώνεται στη συνάρτηση, συμπεριλαμβανομένων των κλήσεων σε άλλες λειτουργίες.
  • υπερβάλλω (# 2): Μέσος χρόνος ανά κλήση για χάλια (χάλια διαιρεμένος με ncalls).
  • όνομα αρχείου: lineno: Το όνομα αρχείου, ο αριθμός γραμμής και το όνομα λειτουργίας για την εν λόγω κλήση.

Τρόπος τροποποίησης των αναφορών cProfile

Από προεπιλογή, cΠροφίλ ταξινομεί την έξοδο με το "τυπικό όνομα", που σημαίνει ότι ταξινομείται με το κείμενο στην ακροδεξιά στήλη (όνομα αρχείου, αριθμός γραμμής κ.λπ.)

Η προεπιλεγμένη μορφή είναι χρήσιμη εάν θέλετε μια γενική, από πάνω προς τα κάτω αναφορά για κάθε μεμονωμένη λειτουργία κλήσης για αναφορά. Αλλά αν προσπαθείτε να φτάσετε στο κάτω μέρος ενός σημείου συμφόρησης, πιθανότατα θα θέλετε πρώτα να αναφέρονται τα πιο χρονοβόρα μέρη του προγράμματος.

Μπορούμε να παράγουμε αυτά τα αποτελέσματα επικαλούμενοςcΠροφίλ λίγο διαφορετικά. Σημειώστε πώς μπορεί να επεξεργαστεί ξανά το κάτω μέρος του παραπάνω προγράμματος για να ταξινομήσετε τα στατιστικά στοιχεία με διαφορετική στήλη (σε αυτήν την περίπτωση ncalls):

if __name__ == '__main__': εισαγωγή cProfile, pstats profiler = cProfile.Profile () profiler.enable () main () profiler.disable () stats = pstats.Stats (profiler) .sort_stats ('ncalls') stats.print_stats () 

Τα αποτελέσματα θα μοιάζουν με αυτό:

Δείτε πώς λειτουργεί όλα αυτά:

  • Αντί να εκτελέσετε μια εντολή μέσω cProfile.run (), το οποίο δεν είναι πολύ ευέλικτο, δημιουργούμε ένα προφίλ αντικείμενο, προφίλ.
  • Όταν θέλουμε να σχεδιάσουμε κάποια ενέργεια, καλούμε πρώτα .επιτρέπω() στην παρουσία αντικειμένου προφίλ, εκτελέστε την ενέργεια και, στη συνέχεια, καλέστε .καθιστώ ανίκανο(). (Αυτός είναι ένας τρόπος για να σχεδιάσετε μόνο μέρος ενός προγράμματος.)
  • ο pstats Η ενότητα χρησιμοποιείται για τον χειρισμό των αποτελεσμάτων που συλλέγονται από το αντικείμενο προφίλ και εκτύπωση αυτών των αποτελεσμάτων.

Συνδυάζοντας ένα αντικείμενο προφίλ και pstats μας επιτρέπει να χειριστούμε τα δεδομένα προφίλ που καταγράφονται - για παράδειγμα, για να ταξινομήσουμε διαφορετικά τα παραγόμενα στατιστικά. Σε αυτό το παράδειγμα, χρησιμοποιώντας .sort_stats ('ncalls') ταξινομεί τα στατιστικά στοιχεία από το ncalls στήλη. Άλλες επιλογές είδους είναι διαθέσιμες.

Πώς να χρησιμοποιήσετε τα αποτελέσματα cProfile για βελτιστοποίηση

Οι διαθέσιμες επιλογές ταξινόμησης για cΠροφίλ Το αποτέλεσμα μας επιτρέπει να εξαλείψουμε πιθανές δυσχέρειες απόδοσης σε ένα πρόγραμμα.

ncalls

Το πρώτο και πιο σημαντικό κομμάτι πληροφοριών με το οποίο μπορείτε να ανακαλύψετε cΠροφίλ είναι ποιες λειτουργίες καλούνται πιο συχνά, μέσω του ncalls στήλη.

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

Στο παραπάνω παράδειγμα, η συνάρτηση Προσθήκη (και η συνάρτηση προσθήκη_2) καλείται επανειλημμένα σε βρόχο. Μετακίνηση του βρόχου στο Προσθήκη Λειτουργεί από μόνη της, ή με κλίση του Προσθήκη λειτουργήσει πλήρως, θα επιλύσει αυτό το πρόβλημα.

τελική ώρα

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

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

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

Τρόπος εξαγωγής δεδομένων cProfile

Εάν θέλετε να χρησιμοποιήσετε cΠροφίλΤα στατιστικά στοιχεία που δημιουργούνται με πιο προηγμένους τρόπους, μπορείτε να τα εξαγάγετε σε ένα αρχείο δεδομένων:

stats = pstats.Stats (προφίλer) stats.dump_stats ('/ path / to / stats_file.dat') 

Αυτό το αρχείο μπορεί να διαβαστεί ξανά χρησιμοποιώντας το pstats ενότητα, μετά ταξινόμηση ή εμφάνιση με pstats. Τα δεδομένα μπορούν επίσης να επαναχρησιμοποιηθούν από άλλα προγράμματα. Δύο παραδείγματα:

  • pyprof2calltree παρέχει λεπτομερείς απεικονίσεις του γραφήματος κλήσεων του προγράμματος και των στατιστικών χρήσης από τα δεδομένα προφίλ. Αυτό το άρθρο παρέχει ένα λεπτομερές πραγματικό παράδειγμα της χρήσης του.
  • φίδι δημιουργεί επίσης οπτικοποιήσεις από cΠροφίλ δεδομένα, αλλά χρησιμοποιεί διαφορετική αναπαράσταση για τα δεδομένα - ένα γράφημα "sunburst" παρά το γράφημα "flame" του pyprof2calltree.

Πέρα από το προφίλ c για προφίλ Python

cΠροφίλ δεν είναι ο μόνος τρόπος για να σχεδιάσετε μια εφαρμογή Python. cΠροφίλ είναι σίγουρα ένας από τους πιο βολικούς τρόπους, δεδομένου ότι συνδυάζεται με την Python. Αλλά άλλοι αξίζουν προσοχή.

Ένα έργο, κατάσκοπος, δημιουργεί ένα προφίλ για μια εφαρμογή Python με δειγματοληψία της δραστηριότητας κλήσης. κατάσκοπος μπορεί να χρησιμοποιηθεί για την εξέταση μιας τρέχουσας εφαρμογής Python χωρίς να χρειάζεται να την σταματήσετε και να την επανεκκινήσετε, και χωρίς να χρειαστεί να αλλάξετε τη βάση κώδικα, ώστε να μπορεί να χρησιμοποιηθεί για το προφίλ εφαρμογών που αναπτύσσονται κατάσκοπος παράγει επίσης ορισμένα στατιστικά στοιχεία σχετικά με τα γενικά έξοδα που προκύπτουν από το χρόνο εκτέλεσης του Python (για παράδειγμα, γενικά απόβλητα συλλογής απορριμμάτων), τα οποία cΠροφίλ δεν.