Karena saya tidak berpikir jawabannya di sini mencakup semuanya, saya ingin membuat tambahan kecil di sini.
Console.WriteLine(string format, params object[] pars)
panggilan string.Format
. Tanda '+' menyiratkan penggabungan string. Saya tidak berpikir ini selalu ada hubungannya dengan gaya; Saya cenderung untuk mencampur dua gaya tergantung pada konteks saya.
Jawaban singkat
Keputusan yang Anda hadapi berkaitan dengan alokasi string. Saya akan mencoba membuatnya sederhana.
Katakan sudah
string s = a + "foo" + b;
Jika Anda menjalankan ini, itu akan mengevaluasi sebagai berikut:
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
tmp
di sini sebenarnya bukan variabel lokal, tetapi ini adalah sementara untuk JIT (didorong pada IL stack). Jika Anda mendorong string pada tumpukan (sepertildstr
dalam IL untuk literal), Anda meletakkan referensi ke pointer string pada stack.
Saat Anda menelepon concat
referensi ini menjadi masalah, karena tidak ada referensi string yang tersedia yang mengandung kedua string. Ini berarti bahwa. NET perlu mengalokasikan blok memori baru, dan kemudian mengisinya dengan dua string. Alasan ini menjadi masalah, adalah karena alokasi relatif mahal.
Yang mengubah pertanyaan menjadi: Bagaimana Anda bisa mengurangi jumlah concat
operasi?
Jadi, jawaban kasarnya adalah: string.Format
untuk> 1 concat, '+' akan bekerja dengan baik untuk 1 concat. Dan jika Anda tidak peduli melakukan optimasi kinerja mikro, string.Format
akan berfungsi dengan baik dalam kasus umum.
Catatan tentang Budaya
Dan kemudian ada sesuatu yang disebut budaya ...
string.Format
memungkinkan Anda untuk digunakan CultureInfo
dalam pemformatan Anda. Operator sederhana '+' menggunakan budaya saat ini.
Ini terutama komentar penting jika Anda sedang menulis format file dan f.ex. double
nilai yang Anda 'tambahkan' ke string. Pada mesin yang berbeda, Anda mungkin berakhir dengan string yang berbeda jika Anda tidak menggunakannya string.Format
dengan eksplisit CultureInfo
.
F.ex. pertimbangkan apa yang terjadi jika Anda mengubah '.' untuk ',' saat menulis file koma-terpisah-nilai Anda ... dalam bahasa Belanda pemisah desimal adalah koma, sehingga pengguna Anda mungkin hanya akan mendapatkan kejutan 'lucu'.
Jawaban yang lebih jelas
Jika Anda tidak tahu ukuran pasti dari string sebelumnya, yang terbaik adalah menggunakan kebijakan seperti ini untuk secara keseluruhan menempatkan buffer yang Anda gunakan. Ruang kendur pertama kali diisi, setelah itu data disalin.
Berkembang berarti mengalokasikan blok memori baru dan menyalin data lama ke buffer baru. Blok memori lama kemudian bisa dilepaskan. Anda mendapatkan intinya pada saat ini: pertumbuhan adalah operasi yang mahal.
Cara paling praktis untuk melakukan ini adalah dengan menggunakan kebijakan penempatan secara keseluruhan. Kebijakan yang paling umum adalah menempatkan buffer secara keseluruhan dalam kekuatan 2. Tentu saja, Anda harus melakukannya sedikit lebih pintar dari itu (karena tidak masuk akal untuk tumbuh dari 1,2,4,8 jika Anda sudah tahu Anda membutuhkan 128 karakter) ) Tapi kamu mendapatkan gambarnya. Kebijakan ini memastikan Anda tidak perlu terlalu banyak operasi mahal yang saya jelaskan di atas.
StringBuilder
adalah kelas yang pada dasarnya secara keseluruhan menempatkan buffer yang mendasari dalam kekuatan dua. string.Format
gunakan di StringBuilder
bawah tenda.
Hal ini membuat keputusan Anda menjadi trade-off dasar antara keseluruhan-dan-tambahkan (-multiple) (dengan budaya) atau hanya mengalokasikan-dan-menambahkan.
string.Format
yang tidak menggunakan fitur format komposit (yaitu hanya sederhana{0}
) dan menggantinya dengan rangkaian string yang jauh lebih cepat. Saya ingin tahu hal seperti itu dapat dicapai dengan IL rewriter yang sudah ada seperti PostSharp.