Java מספקת את הכיתות StringBuffer
ו- String
, String
והמחלקה משמשת לתמרון מחרוזות תווים שלא ניתן לשנות. במילים פשוטות, אובייקטים מסוגם String
נקראים בלבד ואינם ניתנים לשינוי. StringBuffer
המעמד משמש לייצג דמויות שיכולות להיות שונה.
ההבדל הביצועי המשמעותי בין שתי הכיתות הללו StringBuffer
הוא מהיר יותר מאשר String
בעת ביצוע שרשור פשוט. בשנת String
קוד מניפולציה, מחרוזות תווים בשרשור שיגרתי. באמצעות String
הכיתה, שרשור מבוצע בדרך כלל כדלקמן:
מחרוזת str = מחרוזת חדשה ("סטנפורד"); str + = "אבודים !!";
אם היית משתמש StringBuffer
לביצוע אותה שרשור, היית צריך קוד שנראה כך:
StringBuffer str = StringBuffer חדש ("סטנפורד"); str.append ("אבודים !!");
מפתחים בדרך כלל מניחים שהדוגמה הראשונה לעיל יעילה יותר מכיוון שהם חושבים שהדוגמה השנייה, המשתמשת append
בשיטה לשרשור, היא יקרה יותר מהדוגמה הראשונה, שמשתמשת +
במפעיל לשרשור שני String
אובייקטים.
+
המפעיל מופיע מפשע, אבל את הקוד שנוצר מייצר כמה הפתעות. שימוש ב- StringBuffer
for שרשור יכול למעשה לייצר קוד שהוא מהיר משמעותית משימוש ב- String
. כדי לגלות מדוע זה המצב, עלינו לבחון את קוד הביצוע שנוצר משתי הדוגמאות שלנו. קוד הביצה של הדוגמה המשתמשת String
נראה כך:
0 חדש # 7 3 dup 4 ldc # 2 6 invokespecial # 12 9 astore_1 10 new # 8 13 dup 14 aload_1 15 invokestatic # 23 18 invokespecial # 13 21 ldc # 1 23 invokevirtual # 15 26 invokevirtual # 22 29 astore_1
קוד הביצוע במקומות 0 עד 9 מבוצע עבור שורת הקוד הראשונה, כלומר:
מחרוזת str = מחרוזת חדשה ("סטנפורד");
לאחר מכן, קוד הצפייה במיקום 10 עד 29 מבוצע לשרשור:
str + = "אבודים !!";
הדברים נעשים מעניינים כאן. קוד הביס שנוצר לשרשור יוצר StringBuffer
אובייקט ואז קורא append
לשיטתו: StringBuffer
האובייקט הזמני נוצר במיקום 10, append
והשיטה שלו נקראת במיקום 23. מכיוון String
שהמחלקה אינה ניתנת לשינוי, StringBuffer
יש להשתמש בה לשרשור.
לאחר ביצוע השרשור StringBuffer
באובייקט, יש להמיר אותו בחזרה ל- a String
. זה נעשה עם הקריאה toString
לשיטה במקום 26. שיטה זו יוצרת String
אובייקט חדש מהאובייקט הזמני StringBuffer
. יצירת StringBuffer
אובייקט זמני זה והמרתו לאחר מכן חזרה String
לאובייקט הם יקרים מאוד.
לסיכום, שתי שורות הקוד שלמעלה גורמות ליצירת שלושה אובייקטים:
String
אובייקט במיקום 0StringBuffer
אובייקט במיקום 10String
אובייקט במיקום 26
עכשיו, בואו נסתכל על קוד הביס שנוצר לדוגמא באמצעות StringBuffer
:
0 חדש # 8 3 dup 4 ldc # 2 6 invokespecial # 13 9 astore_1 10 aload_1 11 ldc # 1 13 invokevirtual # 15 16 pop
קוד הביצוע במקומות 0 עד 9 מבוצע עבור שורת הקוד הראשונה:
StringBuffer str = StringBuffer חדש ("סטנפורד");
לאחר מכן קוד הביצוע במיקום 10 עד 16 מבוצע לצורך השרשור:
str.append ("אבודים !!");
שימו לב שכמו בדוגמה הראשונה, קוד זה מפעיל את append
שיטת StringBuffer
האובייקט. בשונה מהדוגמה הראשונה, לעומת זאת, אין צורך ליצור זמני StringBuffer
ואז להמיר אותו String
לאובייקט. קוד זה יוצר רק אובייקט אחד, ה- StringBuffer
, במיקום 0.
לסיכום, StringBuffer
השרשור מהיר משמעותית String
מהשרשור. ברור StringBuffer
שיש להשתמש ב- s בפעולה מסוג זה במידת האפשר. אם הפונקציונליות של String
הכיתה רצויה, שקול להשתמש StringBuffer
ב- לשרשור ואז לבצע המרה אחת ל- String
.
למידע נוסף על נושא זה
- " JavaWorld מציג לראשונה טור חדש של ביצועי Java," רג'י האצ'רסון ( JavaWorld, מרץ 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf.html
- "היסודות של ביצועי ג'אווה", רג'י האצ'רסון ( JavaWorld, מרץ 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html
- "בעיית ביצועים או בעיית עיצוב?" רג'י האצ'רסון ( JavaWorld, מרץ 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html
- "אופטימיזציות מהדר", רג'י האצ'רסון ( JavaWorld, מרץ 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html
סיפור זה, "StringBuffer לעומת String" פורסם במקור בהוצאת JavaWorld.