תוצאות החיפוש: Thursday, October 24, 2024.
הקוד PHP שנוצר על ידי מנוע PHP מושפע מאוד מדרך כתיבת הקוד שלך, לא רק במונחי מספר ההוראות לביצוע משימה. ברור שזה משמעותי מאוד, ואני חושב שזה ברור לך.
מה שעשוי להיות פחות ברור הוא שאפילו התחביר של הקוד יכול לשנות לחלוטין את ה-opcode הנוצר, מה שגורם להוצאת יתר של משאבי CPU לביצוע אותו קוד.
במהלך השנים האחרונות, מוצר ה-SaaS שלי גדל הרבה, והוא נתן לי הזדמנות לחקור עומקות יותר ויותר בטכניקות אופטימיזציה לרוץ את עומס העבודה שלי בצורה יעילה ככל האפשר.
התוצאות שראיתי היו מרשימות ועזרו לי הרבה בשחרור זרימת מזומנים חופשית להמשיך את מסע ה-SaaS שלי.
בנקודה זו, תהליך PHP בתוך מוצר ה-SaaS שלי מעבד יותר מ-1.2 מיליארד (עם "b") חבילות נתונים בכל יום על מכונה עם 2vCPU ו-8GB זיכרון. אני משתמש בקבוצת אוטוסקיילינג של AWS כדי להיות מגוון יותר במקרה של פסגות לא צפויות, אבל היא נדירות מוסיפה מכונה שנייה (פעם או פעמיים בשבוע).
בואו ניכנס לנושא המאמר. אני חושב שתמצא אותו מאוד מעניין.
מהו PHP Opcode?
PHP opcode, או operation code, מתייחס להוראות ברמה נמוכה שמבוצעות על ידי מנוע PHP לאחר שהקוד המקורי של PHP שכתבת הוא מורכב.
ב-PHP, הילוכי קוד הוא בזמן ריצה: בעצם, הפעם הראשונה שהקוד שלך נלקח על ידי מנוע PHP, הוא יהיה מורכב לקוד מכונה ידידותי, מקושר (כדי שהמנוע לא יחליף את אותו קוד שוב), ואז מבוצע.
זוהי תיאור פשוט של התהליך:
אחסון Opcode של PHP
אחסון Opcode של PHP מאפשר לך לחסוך שלושה שלבים בתהליך הריצה של הקוד: פירוש הקוד ה-PHP הגולמי, טוקניזציה והידור.
פעם ראשונה שה-Opcode נוצר, הוא נשמר בזיכרון כך שניתן להשתמש בו שוב בבקשות עתידיות. זה מפחית את הצורך של מנוע PHP להידור מחדש את אותו קוד PHP בכל פעם שהוא מורץ, וחוסך הרבה CPU וצריכת זיכרון.
אחסון Opcode הנפוץ ביותר ב-PHP הוא OPCache, והוא כלול כברירת מחדל מ-PHP 5.5 ועד גרסאות עדכניות. הוא יעיל מאוד ונתמך ברוב המקרים.
אחסון הבייטקוד המורץ מחייב בטלת קודם לכל הפריסה. זה בגלל שאם קבצים שהשתנו יש בהם גרסת בייטקוד במטמון, PHP ימשיך לרוץ את הגרסה הישנה של הקוד עד שתרוקן את מטמון Opcode, כך שהקוד החדש יודר ויתקבל פריט מטמון חדש.
איך לחקור Opcode של PHP
כדי להבין כיצד תחביר שונה יכול להשפיע על Opcode של התסריט, אנחנו צריכים דרך לקבל את הקוד המורץ שנוצר על ידי מנוע PHP.
יש שתי דרכים לקבל Opcode.
פונקציות OPCache ילידות
אם יש לך את ההרחבה OPCache מופעלת על המכונה שלך, אתה יכול להשתמש בפונקציות הילידות שלה כדי לקבל Opcode של קובץ PHP ספציפי:
// Force compilation of a script
opcache_compile_file(__DIR__.'/yourscript.php');
// Get OPcache status
$status = opcache_get_status();
// Inspect the script's entry in the cache
print_r($status['scripts'][__DIR__.'/yourscript.php']);
VLD (Vulcan Logic Disassembler) הרחבת PHP
VLD הוא הרחבה PHP פופולרית שפרושה קוד מורכב PHP ומפיקה את האופקודים. זו כלי חזק להבנה איך PHP מפרש ומבצע את הקוד שלך. אחרי ההתקנה, אתה יכול לריצה תוכנית PHP עם VLD מופעל בעזרת הפקט הphp
עם אפשרויות -d
:
php -d vld.active=1 -d vld.execute=0 yourscript.php
היוצאה תכלל מידע מפורט על האופקודים המורכבים, כולל כל פעולה, השורה הקשורה בה, ועוד.
השימוש ב 3v4l (האקרון שלו הוא EVAL)
3v4l הוא כלי ממש שימושי ברשת שמאפשר לך להציץ באופקודים שנוצרו על ידי קוד PHP שאתה מקליד למערכת העריכה. הוא בעצם שרת PHP עם VLD מותקן כך שהוא יכול לתפוש את היוצאת של VLD ולהראות את האופקודים בדפדפן.
מפני שהוא בחינם, אנחנו נשתמש בכלי הברשת הזה לניתוח הבא.
איך ליצור אופקודים PHP יעילים
3v4l מושלם להבנה איך הסינtax שאנחנו משתמשים יכול להשפיע על האופקודים PHP המוצאים בדרך טובה או רעה. בואו נהיה מעלים את הקוד הבא אל 3v4l. שמה את ההגדרה "כל הגיונים התומכים" ולחץ "eval".
namespace App;
strlen('ciao');
אחרי ההרצת הקוד, תפריט תפיסה יופיע בתחתית. תנועה לעמוד VLD כדי לראות את האופקודים המתאימים.
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
5 0 E > INIT_NS_FCALL_BY_NAME 'App%5CSpace%5Cstrlen'
1 SEND_VAL_EX 'ciao'
2 DO_FCALL 0
3 > RETURN 1
שים לב שהפעולה הראשונה היא INIT_NS_FCALL_BY_NAME
. המפרש בונה את שם הפונקציה באמצעות מרחב השמות של הקובץ הנוכחי, אך היא לא קיימת במרחב השמות App\Example
– אז איך זה עובד?
המפרש יבדוק אם הפונקציה קיימת במרחב השמות הנוכחי. אם לא, הוא מנסה לקרוא לפונקציית הליבה המתאימה.
כאן יש לנו הזדמנות להורות למפרש להימנע מבדיקה כפולה זו ולבצע ישירות את פונקציית הליבה.
נסה להוסיף לוכסן הפוך (\
) לפני strlen
ולחץ על "eval":
namespace App;
\strlen('ciao');
בלשונית VLD, תוכל לראות כעת את הקוד האופקודי עם הצהרה אחת בלבד.
line #* E I O op fetch ext return operands
------------------------------------------------------------------------------------- 5 0 E > > RETURN 1
מכיוון שהעברת את המיקום המדויק של הפונקציה, אין צורך לשקול שום גיבוי.
אם אינך אוהב להשתמש בלוכסן הפוך, תוכל לייבא את הפונקציה כמו כל מחלקה אחרת ממרחב השמות השורשי:
namespace App;
use function strlen;
strlen('ciao');
נצל אופטימיזציות אופקוד אוטומטיות
ישנם גם הרבה אוטומטיזמים פנימיים של מנוע PHP ליצירת אופקוד מאופטם המעריך ביטויים סטטיים מראש. זו הייתה אחת הסיבות החשובות ביותר לשיפור הביצועים הגדול של PHP מאז גרסה 7.x.
מודעות לדינמיקות אלה יכולה באמת לעזור לך להפחית צריכת משאבים ולחסוך בעלויות. לאחר שערכתי מחקר זה, התחלתי להשתמש בטריקים אלה לאורך כל הקוד.
אתן לך דוגמה באמצעות קבועים של PHP. הרץ את הסקריפט הזה ב-3v4l:
namespace App;
if (PHP_OS === 'Linux') {
echo "Linux";
}
הסתכל על שתי השורות הראשונות של האופקוד של PHP:
line #* E I O op fetch ext return operands
------------------------------------------------------------------------------------- 5 0 E > FETCH_CONSTANT ~0 'App%5CPHP_OS' 1 IS_IDENTICAL ~0, 'Linux' 2 > JMPZ ~1, ->4 6 3 > ECHO 'Linux' 7 4 > > RETURN 1
FETCH_CONSTANT
מנסה לקבל את הערך של PHP_OS
מהמרחב הנוכחי ואם זה לא קיים שם, הוא יסתכל במרחב הגלובלי. אחר כך, ההוראה IS_IDENTICAL
מבצעת את ההצעה IF
.
עכשיו ננסה להוסיף צרף למונחה הקבילה:
namespace App;
if (\PHP_OS === 'Linux') {
echo "Linux";
}
כפי שאתם יכולים לראות בקוד האופי, המנוע אינו צריך לנסות לקבל את המונחה הקבילה מפני שעכשיו ברור המקום בו היא נמצאת, ובגלל שזהו ערך סטטי הוא כבר יש לו את הערך בזיכרון.
בנוסף, ההצעה IF
נעלמה בגלל שצד השני של ההצעה IS_IDENTICAL
הוא סיסמה סטטית (‘Linux
’) אז ההצעה IF
יכולה להיות סוגרת "true
" בלי העולם העליון של הפעלה המילולית.
זו הסיבה שיש לך הרבה כח להשפיע על הביצועים הסופיים של הקוד PHP שלך.
סיכום
אני מקווה שזה היה נושא מעניין. כפי שהזכרתי בהתחלה של המאמר, אני מקבל הרבה תועלת משימוש בטכניקה זו ולמעשה, הן גם משמשות בחבילות שלנו.
אתם יכולים לראות דוגמה כאן על איך שימשתי את הטיפות האלה בחבילת PHP שלנו כדי להאט את הביצועים שלה.
אם אתם רוצים ללמוד עוד על האתגרים שבניית חברה מוכנה לפתח אנשים, אתם יכולים לעקוב אחריי ב LinkedIn.
Source:
https://dzone.com/articles/php-opcode-improve-application-performance