כשכותבים switch, האם זה נשאר כך ?

21 בדצמבר 2008

תגיות: ,
5 תגובות


טוב, כנראה החוויה הקשה שעברתי עם מחיקת הפוסט של ה FxCop בזמן publish, לא עוזבת אותי,


כי אני ממשיך לכתוב אודותיו.


בכל מקרה, המשכתי קצת לשחק עם הקוד, וגיליתי משהו מעניין, החוק שמחייב אותנו, לממש case עבור כל האפשריות ב enum, עובד רק עם ממשנו יותר מ case אחד, במדה וממשנו רק case אחד, ה Code Analysis יתעלם לגמרי מכל מה שאנחנו כותבים והוא יעביר את הקוד קומפילציה,


אז כדי להבין מה קורה, כתבתי את הקוד הבא, והסתכלתי ב reflector, וגיליתי דברים חדשים,


 




    1     public void f2(MyEnum myEnum)


    2     {


    3         switch (myEnum)


    4         {


    5             case MyEnum.A:


    6                 Console.WriteLine();


    7                 break;


    8             case MyEnum.B:


    9                 Console.WriteLine();


   10                 break;


   11             case MyEnum.C:


   12                 Console.WriteLine();


   13                 break;


   14             default:


   15                 Console.WriteLine();


   16                 break;


   17         }


   18     }


   19 


   20     public void f1(MyEnum myEnum)


   21     {


   22         switch (myEnum)


   23         {


   24             case MyEnum.A:


   25                 Console.WriteLine();


   26                 break;


   27             default:


   28                 Console.WriteLine();


   29                 break;


   30         }


   31     }


   32 }


 

כעת נסתכל מה הקומפיילר באמת עושה, נפתח את ה Refloctor, ונראה מה כתוב שם:

 

 אז הנה הקוד של f2 שבו אנחנו עושים מעבר על יותר מ case אחד:

 

Reflector1

 

 

כמובן בדיוק כמו שאנו מצפים, בלוק של switch שעושה בדיוק מה שכתבנו בקוד,

אבל נציץ על הקוד שמיוצר מ f1, שבו אנחנו עושים case רק על מקרה אחד (ה default לא נחשב)

 

reflactor2

 

אופה, אין שמץ של switch, יש בלוק if רגיל,

מסתבר שמישהו השקיע מחשבה וזמן, כדי לבדוק האם אנחנו עושים case רק על אחד,

לא ברור לי למה, מה היתרון שבלוק if נותן לנו, למה אי אפשר היה להשאיר את זה כ switch,

מה שאני כן יודע, זה שזה דופק לי את ה ForceSwitch, שכתבתי בעמל רב בפוסט הקודם,

 

אשמח אם למישהו יהיה פיתרון.

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

כתיבת תגובה

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

5 תגובות

  1. Rotem Bloom21 בדצמבר 2008 ב 16:39

    היי שלמה,
    האמת שבהתחלה חשבתי שמי שעושה לך את השינוי בקוד הוא ה-JIT ולכן ניסיתי לשלוט עליו בעזרת:
    [assembly: DebuggableAttribute(false, true)]
    שזה אומר בעצם:
    לא לאפשר JIT TRACKING
    ולא לעשות JIT OPTIMIZATION

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

    מעניין באמת אם יש דרך.

    הגב
  2. Rotem Bloom21 בדצמבר 2008 ב 16:43

    דבר נוסף שהוא מעט מוזר זה שבדרך כלל ידוע ש: SWITCH הוא יותר מהיר מאשר ELSE IF ולכן לא ברור מדוע הפקודה הוחלפה.

    מה שנראה לי הכי הגיוני זה שאולי במקרה שאין עוד אפשרויות ב-SWITCH אז IF הוא יותר יעיל ולכן הקומפיילר מחליף את המימוש למשהו יעיל יותר, אבל זו רק השערה.

    מה אתה אומר?

    הגב
  3. Shlomo21 בדצמבר 2008 ב 17:26

    ההתנהגות באמת מוזרה, צריך לחפש מישהו שבאמת מבין בדברים האלו, אני אנסה לשאול את סשה

    הגב
  4. anonymous21 בדצמבר 2008 ב 20:43

    מוזר, האם זה קורה במצב של Debug?
    כי עד כמה שאני יודע במצב כזה לא אמורה להיות אופטימיזציה של הקוד.

    הגב
  5. Shlomo21 בדצמבר 2008 ב 21:25

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

    הגב