ייעול לולאות ב-JavaScript
אלעד אוסדון כתב בבלוג שלו על איך לייעל לולאות שעוברות על אוספים (כמו getElementsByTagName או childNodes) בעזרת טכניקה של שימוש בהשמה למשתנה כתנאי יציאה מהלולאה:
for (var i=0,item;item=someArray[i];i++) {
alert(item);
}
בעצם אופרטור ההשמה (=) מחזיר את הערך שהושם, וברגע שעברנו את סוף ה-collection אז יוחזר לנו null מפעולת ההשמה ולכן נצא מהלולאה כי null מומר ל-false בבדיקות בוליאניות.
ובסוף הפוסט הדגיש: “בלולאה כדאי להשתמש רק במעבר על collection, למשל getElementsByTagName, childNodes, זאת מאחר וריצה על ערכים שעלולים לכלול 0, undefined, null, מחרוזת ריקה או כל ערך השווה ל-false תופסק באמצע.”
כדי להימנע מבעיה זו יש טכניקה נוספת שניתן להשתמש בה. בטכניקה זו מאתחלים שלושה משתנים בתחילת הלולאה: מונה, אורך המערך ומשתנה עבור הפריט.בין האיטרציות משווים בין המונה למשתנה שמחזיק את אורך המערך ובתחילת כל איטרציה מאתחלים את משתנה הפריט בערך הבא:
for(var i=0, len=arr.length, item;i<len;item=arr[++i]){
alert(item);
}
בדרך הזו אנחנו יכולים לעבור על כל אוסף ממוספר מבלי לדאוג לערך שקיים בתוך האוסף.
הסבר לשתי השיטות למה הן יעילות יותר מהשיטה הרגילה (שהוצגה בפוסט של אלעד):
בשיטה הרגילה בכל איטרציה יוצרים מחדש את המשתנה עבור הפריט והוא מושמד בסוף כל איטרציה, לעומת זאת בשיטה שלי ובשיטה של אלעד המשתנה נשאר קיים רק ערכו משתנה, ברגע היציאה מהלולאה הוא מושמד. כמו כן, בשיטה שלי שומרים את אורך המערך “בצד” ובשיטה הרגילה הוא מחושב כל פעם מההתחלה (אורך המערך יכול להשתנות תוך כדי הלולאה או ע”י משפיע אסינכרוני חיצוני). בשיטה של אלעד לעומת שתי השיטות אין התייחסות לאורך המערך, אלא למה שכל פריט בו מכיל (שזה גם מהווה חסרון, אבל לא בביצועים).
מבין שלושת השיטות מבדיקת זמנים שערכתי על מערך מספרים של 50000 איברים השיטה של אלעד הכי יעילה (ב-14% בערך יותר יעילה משלי, וב-33% בערך יותר מהשיטה הרגילה) והשיטה שלי היא במקום השני מבין השלוש (ב-22% בערך יותר יעיל מהשיטה הרגילה). הבדיקות נערכו על פיירפוקס.