StringBuffer לעומת String

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

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

מחרוזת str = מחרוזת חדשה ("סטנפורד"); str + = "אבודים !!";

אם היית משתמש StringBufferלביצוע אותה שרשור, היית צריך קוד שנראה כך:

StringBuffer str = StringBuffer חדש ("סטנפורד"); str.append ("אבודים !!");

מפתחים בדרך כלל מניחים שהדוגמה הראשונה לעיל יעילה יותר מכיוון שהם חושבים שהדוגמה השנייה, המשתמשת appendבשיטה לשרשור, היא יקרה יותר מהדוגמה הראשונה, שמשתמשת +במפעיל לשרשור שני Stringאובייקטים.

+המפעיל מופיע מפשע, אבל את הקוד שנוצר מייצר כמה הפתעות. שימוש ב- StringBufferfor שרשור יכול למעשה לייצר קוד שהוא מהיר משמעותית משימוש ב- 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לאובייקט הם יקרים מאוד.

לסיכום, שתי שורות הקוד שלמעלה גורמות ליצירת שלושה אובייקטים:

  1. Stringאובייקט במיקום 0
  2. StringBufferאובייקט במיקום 10
  3. Stringאובייקט במיקום 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.

רג'י האצ'רסון הוא אוונגליסט טכנולוגי של Sun. הוא מבשר את טכנולוגיות Java 2 של Sun ברחבי העולם ומתרכז ב J2SE ובמנוע הביצועים של HotSpot.

למידע נוסף על נושא זה

  • " 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.