Προγραμματισμός

StringBuffer έναντι String

Η Java παρέχει το StringBuffer και Σειρά τάξεις, και το Σειρά Η κλάση χρησιμοποιείται για τον χειρισμό συμβολοσειρών χαρακτήρων που δεν μπορούν να αλλάξουν. Με απλά λόγια, αντικείμενα του τύπου Σειρά είναι μόνο για ανάγνωση και αμετάβλητο. ο StringBuffer Η κλάση χρησιμοποιείται για την αναπαράσταση χαρακτήρων που μπορούν να τροποποιηθούν.

Η σημαντική διαφορά απόδοσης μεταξύ αυτών των δύο κατηγοριών είναι ότι StringBuffer είναι γρηγορότερο από Σειρά κατά την εκτέλεση απλών συνενώσεων. Σε Σειρά κώδικας χειραγώγησης, οι συμβολοσειρές χαρακτήρων συνδυάζονται συνήθως. Χρησιμοποιώντας το Σειρά τάξη, οι συνενώσεις εκτελούνται συνήθως ως εξής:

 String str = new String ("Στάνφορντ"); str + = "Χαμένο !!"; 

Εάν επρόκειτο να το χρησιμοποιήσετε StringBuffer για να εκτελέσετε την ίδια συνένωση, θα χρειαστείτε κωδικό που μοιάζει με αυτό:

 StringBuffer str = νέο StringBuffer ("Stanford"); str.append ("Lost !!"); 

Οι προγραμματιστές συνήθως υποθέτουν ότι το πρώτο παράδειγμα παραπάνω είναι πιο αποτελεσματικό επειδή πιστεύουν ότι το δεύτερο παράδειγμα, το οποίο χρησιμοποιεί το προσαρτώ μέθοδος συνένωσης, είναι πιο δαπανηρή από το πρώτο παράδειγμα, το οποίο χρησιμοποιεί το + τελεστής να συνενώσει δύο Σειρά αντικείμενα.

ο + Ο τελεστής φαίνεται αθώος, αλλά ο κώδικας που δημιουργείται προκαλεί κάποιες εκπλήξεις. Χρησιμοποιώντας ένα StringBuffer για συνένωση μπορεί στην πραγματικότητα να παράγει κώδικα που είναι πολύ πιο γρήγορος από τη χρήση α Σειρά. Για να ανακαλύψουμε γιατί συμβαίνει αυτό, πρέπει να εξετάσουμε το bytecode που δημιουργήθηκε από τα δύο παραδείγματα. Ο κωδικός bytec για το παράδειγμα που χρησιμοποιεί Σειρά μοιάζει με αυτό:

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 

Ο κωδικός bytec στις θέσεις 0 έως 9 εκτελείται για την πρώτη γραμμή κώδικα, δηλαδή:

 String str = new String ("Στάνφορντ"); 

Στη συνέχεια, ο bytecode στη θέση 10 έως 29 εκτελείται για τη συνένωση:

 str + = "Χαμένο !!"; 

Τα πράγματα γίνονται ενδιαφέροντα εδώ. Ο κωδικός bytec που δημιουργείται για τη συνένωση δημιουργεί ένα StringBuffer αντικείμενο, στη συνέχεια επικαλείται το προσαρτώ μέθοδος: το προσωρινό StringBuffer αντικείμενο δημιουργείται στη θέση 10, και του προσαρτώ Η μέθοδος καλείται στη θέση 23. Επειδή το Σειρά η τάξη είναι αμετάβλητη, α StringBuffer πρέπει να χρησιμοποιηθεί για συνένωση.

Αφού πραγματοποιηθεί η συνένωση στο StringBuffer αντικείμενο, πρέπει να μετατραπεί ξανά σε α Σειρά. Αυτό γίνεται με την κλήση στο toString μέθοδος στην τοποθεσία 26. Αυτή η μέθοδος δημιουργεί ένα νέο Σειρά αντικείμενο από το προσωρινό StringBuffer αντικείμενο. Η δημιουργία αυτού του προσωρινού StringBuffer αντικείμενο και την επακόλουθη μετατροπή του σε α Σειρά αντικείμενο είναι πολύ ακριβό.

Συνοπτικά, οι δύο γραμμές κώδικα παραπάνω έχουν ως αποτέλεσμα τη δημιουργία τριών αντικειμένων:

  1. ΕΝΑ Σειρά αντικείμενο στη θέση 0
  2. ΕΝΑ StringBuffer αντικείμενο στη θέση 10
  3. ΕΝΑ Σειρά αντικείμενο στη θέση 26

Τώρα, ας δούμε τον bytecode που δημιουργήθηκε για το παράδειγμα χρησιμοποιώντας 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 

Ο κωδικός bytec στις θέσεις 0 έως 9 εκτελείται για την πρώτη γραμμή κώδικα:

 StringBuffer str = νέο StringBuffer ("Stanford"); 

Ο bytecode στη θέση 10 έως 16 εκτελείται στη συνέχεια για τη συνένωση:

 str.append ("Lost !!"); 

Παρατηρήστε ότι, όπως συμβαίνει στο πρώτο παράδειγμα, αυτός ο κώδικας επικαλείται το προσαρτώ μέθοδος α StringBuffer αντικείμενο. Σε αντίθεση με το πρώτο παράδειγμα, ωστόσο, δεν υπάρχει ανάγκη δημιουργίας προσωρινής StringBuffer και μετά να το μετατρέψετε σε α Σειρά αντικείμενο. Αυτός ο κώδικας δημιουργεί μόνο ένα αντικείμενο, το StringBuffer, στην τοποθεσία 0.

Συμπερασματικά, StringBuffer η συνένωση είναι σημαντικά ταχύτερη από Σειρά αληλουχία. Προφανώς, StringBuffers θα πρέπει να χρησιμοποιείται σε αυτόν τον τύπο λειτουργίας όταν είναι δυνατόν. Εάν η λειτουργικότητα του Σειρά είναι επιθυμητή η τάξη, σκεφτείτε να χρησιμοποιήσετε ένα StringBuffer για συνένωση και στη συνέχεια εκτέλεση μιας μετατροπής σε Σειρά.

Ο Reggie Hutcherson είναι ευαγγελιστής τεχνολογίας της Sun. Ευαγγελίζει τις τεχνολογίες Java 2 Platform της Sun σε όλο τον κόσμο επικεντρωμένος στο J2SE και στον κινητήρα επιδόσεων HotSpot.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • "JavaWorld κάνει ντεμπούτο στη νέα εβδομαδιαία στήλη απόδοσης Java, "Reggie Hutcherson (JavaWorld, Μάρτιος 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf.html

  • "Τα βασικά της απόδοσης Java", Reggie Hutcherson (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

  • "Βελτιστοποιήσεις μεταγλωττιστή", Reggie Hutcherson (JavaWorld, Μάρτιος 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html

Αυτή η ιστορία, "StringBuffer εναντίον String" δημοσιεύθηκε αρχικά από την JavaWorld.