StringBuilder לעומת StringBuffer בג'אווה

1. סקירה כללית

במאמר קצר זה, נבחן קווי דמיון והבדלים ביניהם StringBuilder ו StringBuffer בג'אווה.

פשוט שים, StringBuilder הוצג בג'אווה 1.5 כתחליף ל- StringBuffer.

2. קווי דמיון

שניהם StringBuilder ו StringBuffer ליצור אובייקטים שמחזיקים ברצף דמויות משתנה. בואו נראה איך זה עובד, ואיך זה משתווה לבלתי משתנה חוּט מעמד:

מחרוזת בלתי ניתנת לשינוי = "abc"; בלתי משתנה = בלתי ניתן לשינוי + "def";

למרות שזה עשוי להיראות כך אנו משנים את אותו אובייקט על ידי הוספתו "Def", אנחנו יוצרים אחד חדש בגלל חוּט לא ניתן לשנות מקרים.

כשמשתמשים באחד מהם StringBuffer אוֹ StringBuilder, אנחנו יכולים להשתמש ב- לְצַרֵף() שיטה:

StringBuffer sb = StringBuffer חדש ("abc"); sb.append ("def");

במקרה זה, לא נוצר אובייקט חדש. קראנו ל לְצַרֵף() שיטה ב sb למשל ושינה את תוכנו. StringBuffer ו StringBuilder הם עצמים ניתנים לשינוי.

3. הבדלים

StringBuffer מסונכרן ולכן בטוח בחוטים.StringBuilder תואם ל- StringBuffer ממשק API אך ללא אחריות לסנכרון.

מכיוון שלא מדובר ביישום בטוח לשרשור, הוא מהיר יותר ומומלץ להשתמש בו במקומות בהם אין צורך בבטיחות הברגה.

3.1. ביצועים

באיטרציות קטנות, ההבדל בביצועים אינו משמעותי. בוא נעשה Micro-benchmark מהיר עם JMH:

@State (Scope.Benchmark) מחלקה סטטית ציבורית MyState {int itations = 1000; מחרוזת ראשונית = "abc"; סיומת מחרוזת = "def"; } @Benchmark ציבורי StringBuffer benchmarkStringBuffer (מצב MyState) {StringBuffer stringBuffer = StringBuffer חדש (state.initial); עבור (int i = 0; i <state.iterations; i ++) {stringBuffer.append (state.suffix); } להחזיר stringBuffer; } @Benchmark ציבורי StringBuilder benchmarkStringBuilder (מצב MyState) {StringBuilder stringBuilder = StringBuilder חדש (state.initial); עבור (int i = 0; i <state.iterations; i ++) {stringBuilder.append (state.suffix); } להחזיר stringBuilder; }

השתמשנו בברירת המחדל תפוקה מצב - כלומר פעולות ליחידת זמן (ציון גבוה יותר עדיף), מה שנותן:

יחידות מידה שוויון ציון Cnt יחידות StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops / s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops / s

אם נגדיל את מספר האיטרציות מ -1k ל -1m אז נקבל:

יחידות מידה שוויון ציון Cnt יחידות StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops / s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops / s

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

4. מסקנות

במילים פשוטות, ה StringBuffer הוא יישום בטוח לשרשור ולכן איטי יותר מ- StringBuilder.

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

לבסוף, כמו תמיד, ניתן למצוא את הקוד ששימש במהלך הדיון ב- GitHub.