בתחרות של קצב החלפת מצב של פין פלט דיגיטלי (Toggle), שנערכה על גבי ה-BBC Micro:bit שלי בין שפת MicroPython לשפת C++, אני בטוח שתוכלו לנחש מי ניצחה… אבל האם אתם יכולים לנחש גם מה היה ההפרש בין השתיים?
כפי שהבטחתי בפוסט הקודם, החלטתי לעמת את סביבת הפיתוח המותאמת-לילדים של ה-BBC Micro:bit, שבה כותבים קוד בשפת MicroPython (שהיא למעשה Python 3 מצומצמת ומותאמת למיקרו-בקרים), עם סביבת הפיתוח המקוונת והרצינית mbed (שתומכת גם היא בלוח הזה ובספריות שנכתבו עבורו). מעבר להבדלים המובנים-מאליהם בממשק ובשפת התכנות, עד כמה התוצר הסופי שונה מבחינת ביצועים?
ראשית, כתבתי קוד בסיסי מאד בפייתון שמחליף שוב ושוב את המצב של פין 0 בלוח מ-HIGH ל-LOW ובחזרה:
from microbit import * x = 0 while True: pin0.write_digital(x) x = 1 - x
קובץ ה-HEX שהקומפיילר הפיק עבור התוכנה הזו היה במשקל 595KB (רובם כמובן לא קשורים לפונקציונליות הספציפית, אלא לכל מה שמסביב).
לקחתי את המולטימטר הכי משוכלל שלי, שיש לו פונקציה של מדידת תדר, והוא הראה תוצאה של 1.338KHz. חשוב לזכור, כמובן, שזו מדידה של ה"גל" המלא, מ-HIGH ל-HIGH, ולמעשה מצב הפלט התחלף בקצב גבוה פי שניים. עדיין, זהו מספר עלוב למדי: אנחנו יכולים לשמוע תדרים יותר גבוהים מזה, למען השם.
כעת עברתי ל-mbed. כאן העניינים התחילו מיד להסתבך. אמנם היה קל מאד להעלות ולהריץ את התוכנית-לדוגמה שמציגה "Hello World" על מטריצת הלדים המובנית, אך כשניסיתי לכתוב תוכנית משלי, איבדתי את הידיים ואת הרגליים. איך נקראות הפקודות הרלוונטיות? באיזו ספריה הן נמצאות? אילו קבועים מוגדרים עבורן? לא היה פשוט למצוא את המידע הזה, ובכל פעם הקומפיילר הציג הודעות שגיאה חדשות ולא צפויות. רק בתום מאבק ממושך הצלחתי להגיע לקוד הזה, שהתקמפל בהצלחה:
#include "MicroBit.h" MicroBit uBit; MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_DIGITAL); int main() { unsigned int x = 0; uBit.init(); while (1) { P0.setDigitalValue(x); x = 1 - x; } }
קובץ ה-HEX שלו שקל "רק" 421KB (בחיי שאני לא יודע למה צריך כל כך הרבה לקוד שנכתב ב-C++), והמולטימטר הראה תדר של 129.9KHz. כן, פי 97 מתוכנת הפייתון. זה לא סתם הבדל גדול, זה אפילו כבר לא מצחיק.
חלק הארי של ההפרש בביצועים נובע, כמובן, מכך ש-MicroPython היא שפה שמפורשת (Interpreted) בזמן אמת. רוב מה שעובר למיקרו-בקר בקובץ ה-HEX הוא למעשה המפרש, שהוא בעצמו תוכנה גדולה וכבדה. תוך כדי ריצה הוא קורא את פקודות הפייתון שכתבתי, מפענח את המשמעות שלהן ואז קורא לפונקציות מובנות משלו כדי לגרום למיקרו-בקר לעשות דברים בהתאם. כשחושבים על זה, מפתיע שההבדל הוא רק פי תשעים ושבעה.
כמובן, זה לא אומר שצריך להשליך את MicroPython לפח. יש לה יתרונות משלה, בעיקר כשמדובר בילדים שנתקלים בעולם התכנות בפעם הראשונה. למעשה, ילד שנכנס רק עכשיו לתחום ויגלה, בעוד כמה שנים, שבעזרת C++ הוא יכול לגרום לקוד שלו לרוץ פי מאה יותר מהר, יזכה לחוויה פוקחת עיניים שאפשר רק לקנא בה.
עדיין, בשביל פרויקטים לא-טריוויאליים, אני אעדיף כמובן להתאמץ ולכתוב בשפה הרצינית. יש הרבה יותר מדי דברים בעולם ה-Embedded שמחייבים עיבוד וניהול מהירים יותר ממה שהאוזן שומעת…
היי אשמח לדעת מאיפה, הזמנת את הלוח, או מאיפה אפשר להזמין לישראל, תודה.
אני קניתי מכאן: https://www.pi-supply.com/product-category/other-micro-computers/bbc-micro-bit/
סביר להניח שאפשר למצוא בעוד מקומות.
אני מודה שאם תוצאות הריצה קשה להתווכח, אבל האם הפייטון עובד כאינטרפרטר ממש? כי בדרך כלל הוא מושמץ על לא עוול (יש לו בעצם בייטקוד וjit).
אני לא יודע אם קוד הפייתון מועבר אליו כ-plain text נטו, אבל בהתחשב בזה שהלוח עצמו מציג לי את הודעות שגיאה ל-Syntax, כולל מספרי שורות ושמות משתנים, אני מניח שזה לא Bytecode. אפשר אולי למצוא מידע נוסף בתיעוד או בקוד המקור של MicroPython…
אוקיי, בדקתי את הנושא, והטקסט לא נקרא ומפוענח שוב ושוב בזמן אמת – אבל גם לא כל כך רחוק מזה!
https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/669549