אז פעם שעברה הכרנו קצת את הקונספט של Jagged Arrays וראינו מה ההבדל ביניהם לMulti-dimensional Arrays.
כזכור, מערך רב מימדי ממומש ע”י מערך חד-מימדי רצוף באורך של מספר התאים שלו.
לעומת זאת, Jagged Array ממומש ע”י מספר מערכים בזכרון שלאו דווקא רצופים זה אחר זה.
עושה רושם שגישה אל מערך רב מימדי אמורה להיות מהירה יותר, שהרי המערך כולו יושב רצוף בזכרון.
עם זאת, באופן מפתיע, מסתבר שגישה אל מערך שהוא Jagged היא יותר מהירה.
הרצתי את הקוד השקול הזה:
|
|
על מערכים גדולים יצא לי שלפעמים לוקח למערך הרב מימדי כמעט פי 2 יותר זמן לבצע פעולה זו מהמערך הJagged.
באופן דומה, אפשר להריץ קוד של קריאות ולראות שגם שם המערך הרב מימדי מפסיד בביצועים.
למה זה קורה?
הסיבה היא כזאת: אמנם מערכים רב מימדיים יושבים ברצף בזכרון, אבל הגישה אליהם מתבצעת באמצעות Indexer. הIndexer הזה הוא למעשה פונקציה לכל דבר, ולכן מתבצעת קריאה לפונקציה כדי להגיע למקום המתאים בזכרון.
הקריאה לפונקציה היא מה שעולה את רוב הזמן.
אז למה לא מרגישים את זה בJagged Array? הרי גם שם אנחנו ניגשים בIndexer, ואפילו פעמיים!
ובכן, הקומפיילר מקמפל גישה למערך חד מימדי בצורה יותר מהירה מגישה לפונקציה: זה מתבצע ע"י פקודות IL ייעודיות לכך:
- stelem.ref – להשמה במערך
- ldelem.ref – לקריאה ממערך
לכן במערכים שהם Jagged, שהם מערכים חד מימדיים לכל דבר, גישה לאיבר מסוים מתבצעת ע"י גישה מהירה.
במערכים רב-מימדיים רגילים, הגישה מתבצעת ע"י קריאה לאחת מהפונקציות:
|
|
לקריאה לפונקציה יש Overhead נוסף, מאחר וצריך לדחוף את הפרמטרים המתאימים במחסנית וכו’.
אז מה המסקנה?
אם אתם משתמשים בקונספט של מערכים רב-מימדיים, והביצועים ממש קריטיים לכם, כדאי לשקול להשתמש בJagged Arrays.
אחרת, אין סיבה לא להשתמש במערכים רב-מימדיים רגילים.
למען האמת, קשה לי להאמין שמישהו משתמש בקונספט של מערכים רב מימדיים.
למעשה, לא יצא להשתמש בהם המון זמן, ובפעם הקודמת שהשתמשתי בהם, זה היה לצורך כתיבת תרגיל חפיפות.
סוף שבוע רב מימדי טוב!