כיצד לייעל את קוד הפייתון שלך עם כלי פרופיל

Kyzd Lyy L T Qwd Hpyytwn Slk M Kly Prwpyl



שיפור ביצועי הקוד של Python היא מיומנות חשובה עבור מפתחים. כלי יצירת פרופיל חיוניים במקרה זה ומקלים על זיהוי הגבלות קוד וחוסר יעילות. מאמר זה בוחן את הדרכים לשימוש בכלי פרופיל לשיפור תוכניות Python. על ידי שליטה במדידת זמני ביצוע, צריכת זיכרון וקריאה לתדרים לתפקוד, אנו יכולים לשפר במדויק.

אופטימיזציה של קוד Python עם כלי פרופיל

הגדרת Google Colab לעבודה לאופטימיזציה של קוד Python עם כלי פרופיל, אנו מתחילים בהגדרת סביבת Google Colab. אם אנחנו חדשים ב-Colab, זוהי פלטפורמה חיונית וחזקה מבוססת ענן המספקת גישה למחברות של Jupyter ולמגוון ספריות Python. אנו ניגשים ל-Colab על ידי ביקור (https://colab.research.google.com/) ויצירת מחברת Python חדשה.

ייבא את ספריות הפרופילים

האופטימיזציה שלנו מסתמכת על שימוש מיומן בספריות פרופילים. שתי ספריות חשובות בהקשר זה הן cProfile ו-line_profiler.







יְבוּא cProfile

יְבוּא line_profiler

ספריית 'cProfile' היא כלי Python מובנה לפרופיל קוד, בעוד 'line_profiler' היא חבילה חיצונית המאפשרת לנו להעמיק עוד יותר, ולנתח את הקוד שורה אחר שורה.



בשלב זה, אנו יוצרים סקריפט Python לדוגמה כדי לחשב את רצף פיבונאצ'י באמצעות פונקציה רקורסיבית. בואו ננתח את התהליך הזה לעומק יותר. רצף פיבונאצ'י הוא קבוצה של מספרים שבה כל מספר עוקב הוא סכום השניים שלפניו. בדרך כלל זה מתחיל עם 0 ו-1, אז הרצף נראה כמו 0, 1, 1, 2, 3, 5, 8, 13, 21 וכן הלאה. זהו רצף מתמטי המשמש בדרך כלל כדוגמה בתכנות בשל אופיו הרקורסיבי.



אנו מגדירים פונקציית Python בשם 'Fibonacci' בפונקציה רקורסיבית Fibonacci. פונקציה זו לוקחת מספר שלם 'n' כארגומנט שלה, המייצג את המיקום ברצף פיבונאצ'י שאנו רוצים לחשב. אנו רוצים לאתר את המספר החמישי ברצף פיבונאצ'י, למשל, אם 'n' שווה ל-5.





def פיבונאצ'י ( נ ) :

לאחר מכן, אנו קובעים מקרה בסיס. מקרה בסיסי ברקורסיה הוא תרחיש שמסיים את השיחות ומחזיר ערך קבוע מראש. ברצף פיבונאצ'י, כאשר 'n' הוא 0 או 1, אנחנו כבר יודעים את התוצאה. מספרי פיבונאצ'י 0 ו-1 הם 0 ו-1, בהתאמה.

אם נ <= 1 :

לַחֲזוֹר נ

הצהרת 'אם' זו קובעת אם 'n' קטן מ-1 או שווה ל-1. אם כן, אנו מחזירים 'n' בעצמו, מכיוון שאין צורך ברקורסיה נוספת.



חישוב רקורסיבי

אם 'n' עולה על 1, נמשיך בחישוב הרקורסי. במקרה זה, עלינו למצוא את מספר פיבונאצ'י 'n'-ה על ידי סיכום מספרי פיבונאצ'י '(n-1)' ו-'(n-2)'. אנו משיגים זאת על ידי ביצוע שתי קריאות רקורסיביות בתוך הפונקציה.

אַחֵר :

לַחֲזוֹר פיבונאצ'י ( n - 1 ) + פיבונאצ'י ( n - 2 )

כאן, 'fibonacci(n - 1)' מחשב את מספר פיבונאצ'י '(n-1)', ו-'fibonacci(n - 2)' מחשב את מספר פיבונאצ'י '(n-2)'. אנו מוסיפים את שני הערכים הללו כדי לקבל את מספר פיבונאצ'י הרצוי במיקום 'n'.

לסיכום, פונקציית 'פיבונאצ'י' זו מחשבת באופן רקורסיבי את מספרי פיבונאצ'י על ידי פירוק הבעיה לתת-בעיות קטנות יותר. הוא מבצע שיחות רקורסיביות עד שהוא מגיע למקרים הבסיסיים (0 או 1), ומחזיר ערכים ידועים. עבור כל 'n' אחר, הוא מחשב את מספר פיבונאצ'י על ידי סיכום התוצאות של שתי קריאות רקורסיביות עבור '(n-1)' ו-'(n-2)'.

למרות שהיישום הזה פשוט לחישוב מספרי פיבונאצ'י, הוא לא היעיל ביותר. בשלבים המאוחרים יותר, נשתמש בכלי הפרופיל כדי לזהות ולמטב את מגבלות הביצועים שלו לזמני ביצוע טובים יותר.

יצירת פרופיל של הקוד באמצעות CProfile

כעת, אנו פרופילים את פונקציית 'פיבונאצ'י' שלנו על ידי שימוש ב-'cProfile'. תרגיל פרופיל זה מספק תובנות לגבי הזמן הנצרך על ידי כל קריאת פונקציה.

cprofiler = cProfile. פּרוֹפִיל ( )

cprofiler. לְאַפשֵׁר ( )

תוֹצָאָה = פיבונאצ'י ( 30 )

cprofiler. להשבית ( )

cprofiler. print_stats ( סוג = 'מִצטַבֵּר' )

בקטע זה, אנו מאתחלים אובייקט 'cProfile', מפעילים את הפרופיל, מבקשים את הפונקציה 'fibonacci' עם 'n=30', מבטלים את הפרופיל, ומציגים את הסטטיסטיקה הממוינת לפי זמן מצטבר. הפרופיל הראשוני הזה נותן לנו סקירה ברמה גבוהה של הפונקציות שצורכות הכי הרבה זמן.

! pip להתקין line_profiler

יְבוּא cProfile

יְבוּא line_profiler

def פיבונאצ'י ( נ ) :

אם נ <= 1 :

לַחֲזוֹר נ

אַחֵר :

לַחֲזוֹר פיבונאצ'י ( n - 1 ) + פיבונאצ'י ( n - 2 )

cprofiler = cProfile. פּרוֹפִיל ( )

cprofiler. לְאַפשֵׁר ( )

תוֹצָאָה = פיבונאצ'י ( 30 )

cprofiler. להשבית ( )

cprofiler. print_stats ( סוג = 'מִצטַבֵּר' )

כדי ליצור פרופיל של הקוד שורה אחר שורה עם line_profiler לניתוח מפורט יותר, אנו משתמשים ב-'line_profiler' כדי לפלח את הקוד שלנו שורה אחר שורה. לפני השימוש ב-'line_profiler', עלינו להתקין את החבילה במאגר Colab.

! pip להתקין line_profiler

כעת, כשיש לנו את ה-'line_profiler' מוכן, נוכל להחיל אותו על פונקציית ה-'fibonacci' שלנו:

%load_ext line_profiler

def פיבונאצ'י ( נ ) :

אם נ <= 1 :

לַחֲזוֹר נ

אַחֵר :

לַחֲזוֹר פיבונאצ'י ( n - 1 ) + פיבונאצ'י ( n - 2 )

%lprun -f fibonacci fibonacci ( 30 )

קטע זה מתחיל בטעינת התוסף 'line_profiler', מגדיר את הפונקציה 'fibonacci' שלנו, ולבסוף משתמש ב-'%lprun' כדי ליצור פרופיל של הפונקציה 'fibonacci' עם 'n=30'. הוא מציע פילוח שורה אחר שורה של זמני ביצוע, ומנקה בדיוק היכן הקוד שלנו מוציא את המשאבים שלו.

לאחר הפעלת כלי הפרופיל לניתוח התוצאות, הוא יוצג עם מערך סטטיסטיקה המציג את מאפייני הביצועים של הקוד שלנו. נתונים סטטיסטיים אלה כוללים את הזמן הכולל המושקע בכל פונקציה ומשך הזמן של כל שורת קוד. לדוגמה, אנו עשויים להבחין שפונקציית פיבונאצ'י משקיעה מעט יותר זמן בחישוב מחדש של הערכים הזהים מספר פעמים. זהו החישוב המיותר וזהו תחום ברור שבו ניתן ליישם אופטימיזציה, או באמצעות שינון או על ידי שימוש באלגוריתמים איטרטיביים.

כעת, אנו מבצעים אופטימיזציות שבהן זיהינו אופטימיזציה פוטנציאלית בפונקציית Fibonacci שלנו. שמנו לב שהפונקציה מחשבת מחדש את אותם מספרי פיבונאצ'י מספר פעמים, וכתוצאה מכך יתירות מיותרת וזמן ביצוע איטי יותר.

כדי לייעל זאת, אנו מיישמים את הזיכרון. שינון הוא טכניקת אופטימיזציה הכוללת אחסון התוצאות שחושבו קודם לכן (במקרה זה, מספרי פיבונאצ'י) ושימוש חוזר בהן בעת ​​הצורך במקום חישובן מחדש. זה מפחית את החישובים המיותרים ומשפר את הביצועים, במיוחד עבור פונקציות רקורסיביות כמו רצף פיבונאצ'י.

כדי ליישם את הזיכרונות בפונקציית Fibonacci שלנו, אנו כותבים את הקוד הבא:

# מילון לאחסון מספרי פיבונאצ'י מחושבים
fib_cache = { }
def פיבונאצ'י ( נ ) :
אם נ <= 1 :
לַחֲזוֹר נ
# בדוק אם התוצאה כבר שמורה במטמון
אם נ ב fib_cache:
לַחֲזוֹר fib_cache [ נ ]
אַחֵר :
# חשב ושמור את התוצאה במטמון
fib_cache [ נ ] = פיבונאצ'י ( n - 1 ) + פיבונאצ'י ( n - 2 )
לַחֲזוֹר fib_cache [ נ ] ,

בגרסה ששונתה זו של פונקציית 'פיבונאצ'י', אנו מציגים מילון 'fib_cache' לאחסון מספרי פיבונאצ'י שחושבו קודם לכן. לפני חישוב מספר פיבונאצ'י, אנו בודקים אם הוא כבר נמצא במטמון. אם כן, נחזיר את התוצאה המאוחסנת במטמון. בכל מקרה אחר, אנו מחשבים אותו, שומרים אותו במטמון ואז מחזירים אותו.

חזרה על הפרופיל והאופטימיזציה

לאחר הטמעת האופטימיזציה (שינון במקרה שלנו), חיוני לחזור על תהליך הפרופיל כדי לדעת את ההשפעה של השינויים שלנו ולהבטיח ששיפרנו את ביצועי הקוד.

פרופיל לאחר אופטימיזציה

אנחנו יכולים להשתמש באותם כלי פרופיל, 'cProfile' ו-'line_profiler', כדי ליצור פרופיל של פונקציית Fibonacci המאופטימלית. על ידי השוואת תוצאות הפרופיל החדשות לתוצאות הקודמות, נוכל למדוד את יעילות האופטימיזציה שלנו.

כך נוכל ליצור פרופיל של פונקציית 'פיבונאצ'י' המותאמת באמצעות 'cProfile':

cprofiler = cProfile. פּרוֹפִיל ( )

cprofiler. לְאַפשֵׁר ( )

תוֹצָאָה = פיבונאצ'י ( 30 )

cprofiler. להשבית ( )

cprofiler. print_stats ( סוג = 'מִצטַבֵּר' )

באמצעות ה-'line_profiler', אנו פרופילים אותו שורה אחר שורה:

%lprun -f fibonacci fibonacci ( 30 )

קוד:

# מילון לאחסון מספרי פיבונאצ'י מחושבים
fib_cache = { }

def פיבונאצ'י ( נ ) :
אם נ <= 1 :
לַחֲזוֹר נ
# בדוק אם התוצאה כבר שמורה במטמון
אם נ ב fib_cache:
לַחֲזוֹר fib_cache [ נ ]
אַחֵר :
# חשב ושמור את התוצאה במטמון
fib_cache [ נ ] = פיבונאצ'י ( n - 1 ) + פיבונאצ'י ( n - 2 )
לַחֲזוֹר fib_cache [ נ ]
cprofiler = cProfile. פּרוֹפִיל ( )
cprofiler. לְאַפשֵׁר ( )

תוֹצָאָה = פיבונאצ'י ( 30 )

cprofiler. להשבית ( )
cprofiler. print_stats ( סוג = 'מִצטַבֵּר' )
%lprun -f fibonacci fibonacci ( 30 )

כדי לנתח את תוצאות הפרופיל לאחר האופטימיזציה, זמני ביצוע מופחתים משמעותית, במיוחד עבור ערכי 'n' גדולים. בגלל שינון, אנו רואים שהפונקציה משקיעה כעת הרבה פחות זמן בחישוב מחדש של מספרי פיבונאצ'י.

שלבים אלו חיוניים בתהליך האופטימיזציה. אופטימיזציה כרוכה בביצוע שינויים מושכלים בקוד שלנו בהתבסס על התצפיות שהושגו מיצירת פרופילים, בעוד שיצירת פרופילים חוזרת מבטיחה שהאופטימיזציות שלנו יניבו את שיפורי הביצועים הצפויים. על ידי יצירת פרופיל איטרטיבי, אופטימיזציה ואימות, אנו יכולים לכוונן עדין את קוד Python שלנו כדי לספק ביצועים טובים יותר ולשפר את חווית המשתמש של היישומים שלנו.

סיכום

במאמר זה, דנו בדוגמה שבה ביצענו אופטימיזציה של קוד Python באמצעות כלי פרופיל בסביבת Google Colab. אתחלנו את הדוגמה עם ההגדרה, ייבאנו את ספריות הפרופיל החיוניות, כתבנו את קודי הדוגמאות, עשינו פרופיל באמצעות 'cProfile' ו-'line_profiler', חישבנו את התוצאות, יישמנו את האופטימיזציות ושיכללנו באופן איטרטיבי את ביצועי הקוד.