התשתית הכי טובה לא יכולה למתכנת הכי גרוע

22 באוקטובר 2009

תגובה אחת

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

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

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

יש הרבה חוסר ידע, שגורם לכך שאנשים יעשו דברים בדרך איטית יותר. הדוגמא של דניאל היתה שימוש באיטרציה כדי להחליף בין שדות, כאשר משפט Update יודע לעשות את זה הרבה יותר מהר ובלי להתבלבל. בעולם התכנה זה שימוש למשל ב for I במקום For Each, על מרחבי נתונים לא לינאריים, שיש להם איטרטורים. כן אני יודע שכולכם יודעם את זה כבר אבל מתכנתים חדשים בצוות שלכם לא תמיד יודעים את מה שאתם יודעים.

לקחת בקוד החלטות אופטימיזציה שמתעלמות מכלל המערכת זה בדרך כלל טעות. קחו את השאלה הבאה, שאני תמיד שואל כאשר מדברים איתי על אופטימיזציה, והיא "לאיזה פרמטר אתה עושה אופטימיזציה בקוד שלך, למהירות או לגודל". התשובה הנפוצה היא למהירות, כדי ליעל כמובן כמה שיותר את פעולה היע"מ. תוצר לואי של ההחלטה הזו זה שהתכנית המיוצרת גדולה יותר, ותופסת יותר מקום בזכרון. במערכות עמוסות, ה Paging של התכנית הזו יהיה גדול יותר. ולמה זה חשוב ? להזכירכם, בזמן גישה אחת לדיסק, להביא דף אחד שנזרק החוצה בגלל העומס, מעבד ממוצע יכול לבצע 30,000,000 פעולות, ועוד ישאר לו עודף. כך שאולי במקרה כזה, צריך דווקא לעשות אופטימיזציה לגודל ולא למהירות ?

אחד הדברים שכואבים בתחום מסדי הנתונים, אבל רלונטיים לכל שימוש במנגנון מטמון במערכות תכנה רגילות, זה עד כמה אני יכול להרשות לעצמי, שהתמונה לא תהיה מעודכנת. דהינו, האם אני יכול לסבול שערך משתנה או נתון יהיו "לא נכונים" פרק זמן כלשהו או לחילופים האם המערכת יכולה לחיות עם "אי דיוקים".  אני יודע שאצל רבים זו בעיה לחשוב, שאתה עושה X=A+B ואחרי זה הערך של X עדיין לא יהיה הערך העדכני לפרק זמן מסויים. אבל אם אתה יודע בוודאות, שאף אחד לא ישתמש ב X לאותו פרק זמן מסויים, אין לך באמת בעיה. גם אם אתה יודע שהשינוי ב X, הוא כל כך קטן, שלא ישפיע באופן משמעותי על התוצאה הסופית, אין לך בעיה. הגמישות הקטנה הזו בזמן, מוליכה בסופו של דבר לחסכון עצום במשאבים. בעולם מסדי הנתונים זה חסכון בשאילתות על ידי שימוש במנגנון כמו Snap Shoot ובעולם הקוד זה שימוש בפחות סמפורים, בכל מקרה, זה שיפור ביצועים ללא צורך בתוספת תשתית.

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

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

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

תגובה אחת

  1. Shmuel Krakower25 באוקטובר 2009 ב 19:14

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

    גדי, תודה על שבאת והעברת שתי הרצאות מעולות על Production Time Debugging ועל Instrumentation במסלול Dot.NET בכנס הביצועים. היה מצויין!

    הגב