Η 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
αντικείμενο και την επακόλουθη μετατροπή του σε α Σειρά
αντικείμενο είναι πολύ ακριβό.
Συνοπτικά, οι δύο γραμμές κώδικα παραπάνω έχουν ως αποτέλεσμα τη δημιουργία τριών αντικειμένων:
- ΕΝΑ
Σειρά
αντικείμενο στη θέση 0 - ΕΝΑ
StringBuffer
αντικείμενο στη θέση 10 - ΕΝΑ
Σειρά
αντικείμενο στη θέση 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
η συνένωση είναι σημαντικά ταχύτερη από Σειρά
αληλουχία. Προφανώς, StringBuffer
s θα πρέπει να χρησιμοποιείται σε αυτόν τον τύπο λειτουργίας όταν είναι δυνατόν. Εάν η λειτουργικότητα του Σειρά
είναι επιθυμητή η τάξη, σκεφτείτε να χρησιμοποιήσετε ένα StringBuffer
για συνένωση και στη συνέχεια εκτέλεση μιας μετατροπής σε Σειρά
.
Μάθετε περισσότερα σχετικά με αυτό το θέμα
- "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.