Εικόνα από συγγραφέα
Ως προγραμματιστής λογισμικού, πιθανότατα θα έχετε ακούσει το απόσπασμα «Η πρόωρη βελτιστοποίηση είναι η ρίζα όλου του κακού»— περισσότερες από μία φορές — στην καριέρα σας. Ενώ η βελτιστοποίηση μπορεί να μην είναι εξαιρετικά χρήσιμη (ή απολύτως απαραίτητη) για μικρά έργα, η δημιουργία προφίλ είναι συχνά χρήσιμη.
Αφού ολοκληρώσετε την κωδικοποίηση μιας ενότητας, είναι καλή πρακτική να δημιουργείτε προφίλ του κώδικά σας για να μετρήσετε πόσο χρόνο χρειάζεται για να εκτελεστεί καθεμία από τις ενότητες. Αυτό μπορεί να βοηθήσει στον εντοπισμό μυρωδιών κώδικα και να καθοδηγήσει βελτιστοποιήσεις για τη βελτίωση της ποιότητας του κώδικα. Οπότε πάντα το προφίλ του κώδικά σας πριν από τη βελτιστοποίηση!
Για να κάνετε τα πρώτα βήματα, αυτός ο οδηγός θα σας βοηθήσει να ξεκινήσετε με τη δημιουργία προφίλ στην Python—χρησιμοποιώντας το ενσωματωμένο timeit και cΠροφίλ ενότητες. Θα μάθετε να χρησιμοποιείτε τόσο τη διεπαφή γραμμής εντολών όσο και τα ισοδύναμα καλούμενα μέσα σε σενάρια Python.
Η λειτουργική μονάδα timeit είναι μέρος της τυπικής βιβλιοθήκης Python και προσφέρει μερικές πρακτικές λειτουργίες που μπορούν να χρησιμοποιηθούν για τον χρονισμό σύντομων αποσπασμάτων κώδικα.
Ας πάρουμε ένα απλό παράδειγμα αντιστροφής μιας λίστας Python. Θα μετρήσουμε τους χρόνους εκτέλεσης για τη λήψη ενός αντίστροφου αντιγράφου της λίστας χρησιμοποιώντας:
- ο
reversed()
λειτουργία, και - τεμαχισμός λίστας.
>>> nums=[6,9,2,3,7]
>>> list(reversed(nums))
[7, 3, 2, 9, 6]
>>> nums[::-1]
[7, 3, 2, 9, 6]
Χρόνος εκτέλεσης στη Γραμμή εντολών
Μπορείτε να τρέξετε timeit
στη γραμμή εντολών χρησιμοποιώντας τη σύνταξη:
$ python -m timeit -s 'setup-code' -n 'number' -r 'repeat' 'stmt'
Απαιτείται να παράσχετε τη δήλωση stmt
του οποίου ο χρόνος εκτέλεσης πρέπει να μετρηθεί.
Μπορείτε να καθορίσετε το setup
κωδικοποιήστε όταν χρειάζεται—χρησιμοποιώντας τη σύντομη επιλογή -s ή τη μεγάλη επιλογή –setup. Ο κωδικός εγκατάστασης θα εκτελεστεί μόνο μία φορά.
Η number
χρόνους εκτέλεσης της πρότασης: η σύντομη επιλογή -n ή η μεγάλη επιλογή -ο αριθμός είναι προαιρετική. Και πόσες φορές θα επαναλάβετε αυτόν τον κύκλο: η σύντομη επιλογή -r ή η μεγάλη επιλογή - η επανάληψη είναι επίσης προαιρετική.
Ας δούμε τα παραπάνω στην πράξη για το παράδειγμά μας:
Εδώ η δημιουργία της λίστας είναι η setup
κωδικός και η αντιστροφή της λίστας είναι η δήλωση που πρέπει να χρονομετρηθεί:
$ python -m timeit -s 'nums=[6,9,2,3,7]' 'list(reversed(nums))'
500000 loops, best of 5: 695 nsec per loop
Όταν δεν καθορίζετε τιμές για repeat
, χρησιμοποιείται η προεπιλεγμένη τιμή 5. Και όταν δεν διευκρινίζεις number
, ο κώδικας εκτελείται όσες φορές χρειάζεται, ώστε να φτάσει ο συνολικός χρόνος τουλάχιστον 0.2 δευτερόλεπτα.
Αυτό το παράδειγμα ορίζει ρητά τον αριθμό των φορών που θα εκτελεστεί η πρόταση:
$ python -m timeit -s 'nums=[6,9,2,3,7]' -n 100Bu000 'list(reversed(nums))'
100000 loops, best of 5: 540 nsec per loop
Η προεπιλεγμένη τιμή του repeat
είναι 5, αλλά μπορούμε να το ορίσουμε σε οποιαδήποτε κατάλληλη τιμή:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' -r 3 'list(reversed(nums))'
500000 loops, best of 3: 663 nsec per loop
Ας χρονομετρήσουμε επίσης την προσέγγιση τεμαχισμού λίστας:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' 'nums[::-1]'
1000000 loops, best of 5: 142 nsec per loop
Η προσέγγιση τεμαχισμού λίστας φαίνεται να είναι πιο γρήγορη (όλα τα παραδείγματα βρίσκονται στην Python 3.10 στο Ubuntu 22.04).
Εκτέλεση χρόνου σε σενάριο Python
Εδώ είναι το ισοδύναμο του χρόνου εκτέλεσης μέσα στο σενάριο Python:
import timeit setup = 'nums=[9,2,3,7,6]'
number = 100000
stmt1 = 'list(reversed(nums))'
stmt2 = 'nums[::-1]' t1 = timeit.timeit(setup=setup,stmt=stmt1,number=number)
t2 = timeit.timeit(setup=setup,stmt=stmt2,number=number) print(f"Using reversed() fn.: {t1}")
print(f"Using list slicing: {t2}")
Η timeit()
Το callable επιστρέφει το χρόνο εκτέλεσης του stmt
for number
των καιρών. Σημειώστε ότι μπορούμε να αναφέρουμε ρητά τον αριθμό των φορών που πρέπει να τρέξουμε ή να κάνουμε number
πάρτε την προεπιλεγμένη τιμή 1000000.
Output >>
Using reversed() fn.: 0.08982690000000002
Using list slicing: 0.015550800000000004
Αυτό εκτελεί τη δήλωση—χωρίς να επαναλάβει τη λειτουργία του χρονοδιακόπτη—για το καθορισμένο number
φορές και επιστρέφει το χρόνο εκτέλεσης. Είναι επίσης αρκετά συνηθισμένο στη χρήση time.repeat()
και αφιερώστε τον ελάχιστο χρόνο όπως φαίνεται:
import timeit setup = 'nums=[9,2,3,7,6]'
number = 100000
stmt1 = 'list(reversed(nums))'
stmt2 = 'nums[::-1]' t1 = min(timeit.repeat(setup=setup,stmt=stmt1,number=number))
t2 = min(timeit.repeat(setup=setup,stmt=stmt2,number=number)) print(f"Using reversed() fn.: {t1}")
print(f"Using list slicing: {t2}")
Αυτό θα επαναλάβει τη διαδικασία εκτέλεσης του κώδικα number
των καιρών repeat
πολλές φορές και επιστρέφει τον ελάχιστο χρόνο εκτέλεσης. Εδώ έχουμε 5 επαναλήψεις από 100000 φορές η καθεμία.
Output >>
Using reversed() fn.: 0.055375300000000016
Using list slicing: 0.015101400000000043
Είδαμε πώς το timeit μπορεί να χρησιμοποιηθεί για τη μέτρηση των χρόνων εκτέλεσης των σύντομων αποσπασμάτων κώδικα. Ωστόσο, στην πράξη, είναι πιο χρήσιμο το προφίλ ενός ολόκληρου σεναρίου Python.
Αυτό θα μας δώσει τους χρόνους εκτέλεσης όλων των συναρτήσεων και των κλήσεων μεθόδων—συμπεριλαμβανομένων των ενσωματωμένων συναρτήσεων και μεθόδων. Έτσι μπορούμε να έχουμε μια καλύτερη ιδέα για τις πιο ακριβές κλήσεις συναρτήσεων και να εντοπίσουμε ευκαιρίες για βελτιστοποίηση. Για παράδειγμα: μπορεί να υπάρχει μια κλήση API που είναι πολύ αργή. Ή μια συνάρτηση μπορεί να έχει έναν βρόχο που μπορεί να αντικατασταθεί από μια πιο Pythonic έκφραση κατανόησης.
Ας μάθουμε πώς να δημιουργείτε προφίλ σε σενάρια Python χρησιμοποιώντας τη λειτουργική μονάδα cProfile (επίσης μέρος της τυπικής βιβλιοθήκης Python).
Εξετάστε το ακόλουθο σενάριο Python:
# main.py
import time def func(num): for i in range(num): print(i) def another_func(num): time.sleep(num) print(f"Slept for {num} seconds") def useful_func(nums, target): if target in nums: return nums.index(target) if __name__ == "__main__": func(1000) another_func(20) useful_func([2, 8, 12, 4], 12)
Εδώ έχουμε τρεις λειτουργίες:
func()
που περιηγείται σε μια σειρά αριθμών και τους εκτυπώνει.another func()
που περιέχει μια κλήση προς τοsleep()
λειτουργία.useful_func()
που επιστρέφει το ευρετήριο ενός αριθμού στόχου στη λίστα (εάν ο στόχος υπάρχει στη λίστα).
Οι παραπάνω συναρτήσεις θα καλούνται κάθε φορά που εκτελείτε το σενάριο main.py.
Εκτέλεση cProfile στη γραμμή εντολών
Εκτελέστε το cProfile στη γραμμή εντολών χρησιμοποιώντας:
python3 -m file-name.py
Εδώ ονομάσαμε το αρχείο main.py:
python3 -m main.py
Εκτελώντας αυτό θα πρέπει να έχετε την ακόλουθη έξοδο:
Output >> 0 ... 999 Slept for 20 seconds
Και το παρακάτω προφίλ:
Εδώ, ncalls
αναφέρεται στον αριθμό των κλήσεων στη λειτουργία και percall
αναφέρεται στον χρόνο ανά κλήση λειτουργίας. Αν η τιμή του ncalls
είναι μεγαλύτερο από ένα, λοιπόν percall
είναι ο μέσος χρόνος για όλες τις κλήσεις.
Ο χρόνος εκτέλεσης του σεναρίου κυριαρχείται από another_func
που χρησιμοποιεί το ενσωματωμένο sleep
κλήση λειτουργίας (αδράνει για 20 δευτερόλεπτα). Το βλέπουμε αυτό print
Οι κλήσεις λειτουργιών είναι επίσης αρκετά ακριβές.
Χρήση cProfile στο σενάριο Python
Ενώ η εκτέλεση του cProfile στη γραμμή εντολών λειτουργεί καλά, μπορείτε επίσης να προσθέσετε τη λειτουργία δημιουργίας προφίλ στο σενάριο Python. Μπορείτε να χρησιμοποιήσετε το cProfile σε συνδυασμό με το μονάδα pstats για δημιουργία προφίλ και πρόσβαση σε στατιστικά στοιχεία.
Ως βέλτιστη πρακτική για να χειριστείτε καλύτερα τη ρύθμιση πόρων και το teardown, χρησιμοποιήστε τη δήλωση with και δημιουργήστε ένα αντικείμενο προφίλ που χρησιμοποιείται ως διαχειριστής περιβάλλοντος:
# main.py
import pstats
import time
import cProfile def func(num): for i in range(num): print(i) def another_func(num): time.sleep(num) print(f"Slept for {num} seconds") def useful_func(nums, target): if target in nums: return nums.index(target) if __name__ == "__main__": with cProfile.Profile() as profile: func(1000) another_func(20) useful_func([2, 8, 12, 4], 12) profile_result = pstats.Stats(profile) profile_result.print_stats()
Ας ρίξουμε μια πιο προσεκτική ματιά στο προφίλ εξόδου που δημιουργήθηκε:
Όταν δημιουργείτε προφίλ σε ένα μεγάλο σενάριο, θα είναι χρήσιμο ταξινομήστε τα αποτελέσματα κατά χρόνο εκτέλεσης. Για να το κάνετε αυτό, μπορείτε να καλέσετε sort_stats
στο αντικείμενο προφίλ και ταξινομήστε με βάση το χρόνο εκτέλεσης:
...
if __name__ == "__main__": with cProfile.Profile() as profile: func(1000) another_func(20) useful_func([2, 8, 12, 4], 12) profile_result = pstats.Stats(profile) profile_result.sort_stats(pstats.SortKey.TIME) profile_result.print_stats()
Όταν εκτελείτε τώρα το σενάριο, θα πρέπει να μπορείτε να δείτε τα αποτελέσματα ταξινομημένα κατά χρόνο:
Ελπίζω αυτός ο οδηγός να σας βοηθήσει να ξεκινήσετε με τη δημιουργία προφίλ στην Python. Να θυμάστε πάντα, ότι οι βελτιστοποιήσεις δεν πρέπει ποτέ να βαρύνουν την αναγνωσιμότητα. Αν ενδιαφέρεστε να μάθετε για άλλους προφίλ, συμπεριλαμβανομένων των πακέτων Python τρίτων, ρίξτε μια ματιά σε αυτό άρθρο για τους προγραμματιστές προφίλ Python.
Bala Priya C είναι προγραμματιστής και τεχνικός συγγραφέας από την Ινδία. Της αρέσει να εργάζεται στη διασταύρωση των μαθηματικών, του προγραμματισμού, της επιστήμης δεδομένων και της δημιουργίας περιεχομένου. Οι τομείς ενδιαφέροντος και εξειδίκευσής της περιλαμβάνουν τα DevOps, την επιστήμη δεδομένων και την επεξεργασία φυσικής γλώσσας. Της αρέσει να διαβάζει, να γράφει, να κωδικοποιεί και τον καφέ! Επί του παρόντος, εργάζεται για να μάθει και να μοιράζεται τις γνώσεις της με την κοινότητα προγραμματιστών, γράφοντας σεμινάρια, οδηγούς με οδηγίες, απόψεις και πολλά άλλα.
- SEO Powered Content & PR Distribution. Ενισχύστε σήμερα.
- PlatoData.Network Vertical Generative Ai. Ενδυναμώστε τον εαυτό σας. Πρόσβαση εδώ.
- PlatoAiStream. Web3 Intelligence. Ενισχύθηκε η γνώση. Πρόσβαση εδώ.
- PlatoESG. Αυτοκίνητο / EVs, Ανθρακας, Cleantech, Ενέργεια, Περιβάλλον, Ηλιακός, Διαχείριση των αποβλήτων. Πρόσβαση εδώ.
- PlatoHealth. Ευφυΐα βιοτεχνολογίας και κλινικών δοκιμών. Πρόσβαση εδώ.
- ChartPrime. Ανεβάστε το Trading Game σας με το ChartPrime. Πρόσβαση εδώ.
- BlockOffsets. Εκσυγχρονισμός της περιβαλλοντικής αντιστάθμισης ιδιοκτησίας. Πρόσβαση εδώ.
- πηγή: https://www.kdnuggets.com/profiling-python-code-using-timeit-and-cprofile?utm_source=rss&utm_medium=rss&utm_campaign=profiling-python-code-using-timeit-and-cprofile
- :είναι
- :δεν
- 10
- 100000
- 12
- 13
- 15%
- 17
- 19
- 20
- 22
- 7
- 8
- 9
- a
- Ικανός
- Σχετικα
- πάνω από
- απολύτως
- πρόσβαση
- ACM
- απέναντι
- Ενέργειες
- προσθέτω
- Όλα
- Επίσης
- πάντοτε
- an
- και
- κάθε
- api
- πλησιάζω
- ΕΙΝΑΙ
- περιοχές
- AS
- At
- συγγραφικός
- μέσος
- βασίζονται
- BE
- πριν
- ΚΑΛΎΤΕΡΟΣ
- Καλύτερα
- και οι δύο
- ενσωματωμένο
- αλλά
- by
- κλήση
- που ονομάζεται
- κλήσεις
- CAN
- Μπορεί να πάρει
- Σταδιοδρομία
- CFM
- έλεγχος
- πιο κοντά
- κωδικός
- Κωδικοποίηση
- Ελάτε
- Κοινός
- κοινότητα
- Περιέχει
- περιεχόμενο
- δημιουργία περιεχομένου
- συμφραζόμενα
- ευκολία
- Κόστος
- σε συνδυασμό
- δημιουργία
- δημιουργία
- δημιουργία
- Τη στιγμή
- κύκλος
- ημερομηνία
- επιστημονικά δεδομένα
- Προεπιλογή
- Εργολάβος
- DevOps
- do
- Μην
- κάθε
- Ολόκληρος
- Ισοδύναμος
- παράδειγμα
- παραδείγματα
- εκτελέσει
- εκτέλεση
- ακριβά
- εξειδίκευση
- έκφραση
- γρηγορότερα
- λίγοι
- Αρχεία
- τέλος
- Όνομα
- πρώτα βήματα
- Εξής
- Για
- από
- λειτουργία
- λειτουργικότητα
- λειτουργίες
- παράγεται
- παίρνω
- Δώστε
- καλός
- μεγαλύτερη
- καθοδηγήσει
- Οδηγοί
- λαβή
- Έχω
- ακούσει
- βοήθεια
- χρήσιμο
- βοηθά
- αυτήν
- εδώ
- ελπίζω
- Πως
- Πώς να
- Ωστόσο
- HTML
- HTTPS
- i
- ιδέα
- προσδιορίσει
- if
- εισαγωγή
- βελτίωση
- in
- περιλαμβάνουν
- Συμπεριλαμβανομένου
- ευρετήριο
- Ινδία
- μέσα
- τόκος
- ενδιαφερόμενος
- περιβάλλον λειτουργίας
- διασταύρωση
- IT
- KDnuggets
- γνώση
- Γλώσσα
- large
- ΜΑΘΑΊΝΩ
- μάθηση
- ελάχιστα
- Βιβλιοθήκη
- Πιθανός
- συμπαθεί
- γραμμή
- Λιστα
- Μακριά
- ματιά
- Κυρίως
- κάνω
- διευθυντής
- πολοί
- μαθηματικά
- Ενδέχεται..
- μέτρο
- μετράται
- αναφέρω
- μέθοδος
- μέθοδοι
- ενδέχεται να
- ελάχιστο
- ενότητα
- ενότητες
- περισσότερο
- Ονομάστηκε
- Φυσικό
- Φυσική γλώσσα
- Επεξεργασία φυσικής γλώσσας
- απαραίτητος
- που απαιτούνται
- ποτέ
- Ειδοποίηση..
- τώρα
- αριθμός
- αριθμοί
- αντικείμενο
- την απόκτηση
- of
- προσφορές
- συχνά
- on
- μια φορά
- ONE
- αποκλειστικά
- Γνώμη
- Ευκαιρίες
- βελτιστοποίηση
- Επιλογή
- or
- ΑΛΛΑ
- δικός μας
- έξω
- παραγωγή
- Packages
- μέρος
- για
- κομμάτια
- Πλάτων
- Πληροφορία δεδομένων Plato
- Πλάτωνα δεδομένα
- πρακτική
- παρόν
- εκτυπώσεις
- διαδικασια μας
- μεταποίηση
- Προφίλ ⬇️
- προφίλ
- Προγραμματισμός
- έργα
- παρέχουν
- Python
- ποιότητα
- παραθέτω
- σειρά
- φθάσουν
- Ανάγνωση
- αναφέρεται
- θυμάμαι
- επαναλαμβάνω
- αντικατασταθούν
- απαιτείται
- πόρος
- Αποτελέσματα
- απόδοση
- Επιστροφές
- ρίζα
- τρέξιμο
- τρέξιμο
- τρέχει
- s
- Επιστήμη
- γραφή
- Εφαρμογές
- δευτερόλεπτα
- τμήματα
- δείτε
- φαίνεται
- δει
- σειρά
- Σέτς
- setup
- μοιράζονται
- αυτή
- Κοντά
- θα πρέπει να
- παρουσιάζεται
- Απλούς
- επιβραδύνουν
- small
- So
- λογισμικό
- καθορίζεται
- πρότυπο
- ξεκίνησε
- Δήλωση
- στατιστική
- Βήματα
- κατάλληλος
- Σούπερ
- σύνταξη
- T1
- Πάρτε
- παίρνει
- στόχος
- teardown
- Τεχνικός
- από
- ότι
- Η
- Τους
- τότε
- Εκεί.
- τρίτους
- αυτό
- τρία
- Μέσω
- ώρα
- Χρονικά
- φορές
- προς την
- πολύ
- Σύνολο
- tutorials
- Ubuntu
- us
- χρήση
- μεταχειρισμένος
- χρησιμοποιεί
- χρησιμοποιώντας
- αξία
- Αξίες
- we
- πότε
- ενώ
- του οποίου
- θα
- με
- εργαζόμενος
- λειτουργεί
- συγγραφέας
- γραφή
- εσείς
- Σας
- zephyrnet