Berapa banyak objek String yang akan dibuat saat menggunakan tanda plus pada kode di bawah ini?
String result = "1" + "2" + "3" + "4";
Jika seperti di bawah ini, saya akan mengatakan tiga objek String: "1", "2", "12".
String result = "1" + "2";
Saya juga tahu bahwa objek String di-cache di String Intern Pool / Table untuk peningkatan kinerja, tapi bukan itu pertanyaannya.
Jawaban:
Anehnya, itu tergantung.
Jika Anda melakukan ini dengan metode:
kemudian compiler tampaknya memancarkan kode menggunakan
String.Concat
@Joachim menjawab (+1 padanya btw).Jika Anda mendefinisikannya sebagai konstanta , misalnya:
atau sebagai literal , seperti pada pertanyaan awal:
maka kompilator akan mengoptimalkan
+
tanda - tanda tersebut. Ini setara dengan:Selanjutnya, kompilator akan menghapus ekspresi konstanta asing, dan hanya memancarkannya jika digunakan atau diekspos. Misalnya, program ini:
Hanya menghasilkan satu string- konstanta
result
(sama dengan "1234").one
dantwo
tidak muncul di IL yang dihasilkan.Perlu diingat bahwa mungkin ada pengoptimalan lebih lanjut pada waktu proses. Saya hanya mengikuti apa yang IL diproduksi.
Akhirnya, dalam hal interning, konstanta dan literal diinternir, tetapi nilai yang diinternir adalah nilai konstanta yang dihasilkan di IL, bukan literal. Ini berarti bahwa Anda mungkin mendapatkan lebih sedikit objek string dari yang Anda harapkan, karena beberapa konstanta atau literal yang didefinisikan secara identik sebenarnya akan menjadi objek yang sama! Ini diilustrasikan sebagai berikut:
Dalam kasus di mana String digabungkan dalam satu lingkaran (atau sebaliknya secara dinamis), Anda berakhir dengan satu string tambahan per penggabungan. Misalnya, berikut ini membuat 12 instance string: 2 konstanta + 10 iterasi, masing-masing menghasilkan instance String baru:
Tetapi (juga secara mengejutkan), beberapa penggabungan yang berurutan digabungkan oleh kompilator menjadi satu penggabungan multi-string. Misalnya, program ini juga hanya menghasilkan 12 instance string! Ini karena " Meskipun Anda menggunakan beberapa + operator dalam satu pernyataan, konten string hanya akan disalin sekali. "
sumber
string s = ""; for (int i = 0; i < n; i++) s += "a";
Jawaban Chris Shain sangat bagus. Sebagai orang yang menulis pengoptimal rangkaian string, saya hanya akan menambahkan dua poin menarik tambahan.
Yang pertama adalah bahwa pengoptimal penggabungan pada dasarnya mengabaikan tanda kurung dan asosiasi kiri jika dapat melakukannya dengan aman. Misalkan Anda memiliki metode M () yang mengembalikan string. Jika Anda mengatakan:
maka kompilator beralasan bahwa operator penjumlahan dibiarkan asosiatif, dan oleh karena itu ini sama dengan:
Tapi ini:
sama dengan
jadi itu adalah penggabungan string konstan
"CD"
denganM()
.Faktanya, pengoptimal penggabungan menyadari bahwa penggabungan string adalah asosiatif , dan menghasilkan
String.Concat(M(), "AB")
untuk contoh pertama, meskipun itu melanggar asosiasi kiri.Anda bahkan dapat melakukan ini:
dan kami masih akan menghasilkan
String.Concat(M(), "EF", M())
.Hal menarik kedua adalah bahwa string kosong dan kosong dioptimalkan. Jadi jika Anda melakukan ini:
Anda akan mendapatkan
String.Concat(M(), M())
Sebuah pertanyaan menarik kemudian muncul: bagaimana dengan ini?
Kami tidak bisa mengoptimalkannya hingga
karena
M()
mungkin mengembalikan null, tetapiString.Concat(M(), null)
akan mengembalikan string kosong jikaM()
mengembalikan null. Jadi yang kita lakukan justru mengurangiuntuk
Dengan demikian menunjukkan bahwa penggabungan string sebenarnya tidak perlu dipanggil
String.Concat
sama sekali.Untuk bacaan lebih lanjut tentang subjek ini, lihat
Mengapa String.Concat tidak dioptimalkan untuk StringBuilder.Append?
sumber
("C" + "D") + M())
menghasilkanString.Concat("CD", M())
, tidakString.Concat(M(), "AB")
. Dan lebih jauh ke bawah,(M() + "E") + (null + M())
harus menghasilkanString.Concat(M(), "E", M())
, bukanString.Concat(M(), M())
.Saya menemukan jawabannya di MSDN. Satu.
Cara: Menggabungkan Beberapa String (Panduan Pemrograman C #)
sumber
Hanya satu. Kompiler C # akan melipat konstanta string dan karenanya pada dasarnya dikompilasi menjadi
sumber
Saya ragu ini diamanatkan oleh standar atau spesifikasi apa pun. Satu versi kemungkinan dapat melakukan sesuatu yang berbeda dari yang lain.
sumber
Pertama, karena bersifat statis, kompilator akan dapat mengoptimalkannya ke satu string pada waktu kompilasi.
Jika mereka dinamis, mereka akan dioptimalkan untuk satu panggilan ke String.Concat (string, string, string, string) .
sumber