it-swarm-id.com

String vs. StringBuilder

Saya memahami perbedaan antara String dan StringBuilder (StringBuilder yang bisa berubah-ubah) tetapi apakah ada perbedaan kinerja yang besar antara keduanya?

Program yang sedang saya kerjakan memiliki banyak string case-driven yang ditambahkan (500+). Apakah menggunakan StringBuilder pilihan yang lebih baik?

204
Kuvo

Ya, perbedaan kinerja sangat signifikan. Lihat artikel KB " Cara meningkatkan kinerja rangkaian string dalam Visual C # ".

Saya selalu mencoba kode untuk kejelasan terlebih dahulu, dan kemudian mengoptimalkan kinerja nanti. Itu jauh lebih mudah daripada melakukannya sebaliknya! Namun, setelah melihat perbedaan kinerja yang sangat besar dalam aplikasi saya antara keduanya, saya sekarang memikirkannya sedikit lebih hati-hati.

Untungnya, relatif mudah untuk menjalankan analisis kinerja pada kode Anda untuk melihat di mana Anda menghabiskan waktu, dan kemudian memodifikasinya untuk menggunakan StringBuilder di mana diperlukan.

225
Jay Bazuzi

Untuk memperjelas apa yang dikatakan Gillian tentang 4 string, jika Anda memiliki sesuatu seperti ini:

string a,b,c,d;
 a = b + c + d;

maka akan lebih cepat menggunakan string dan operator plus. Ini karena (seperti Java, seperti yang ditunjukkan Eric), secara internal menggunakan StringBuilder secara otomatis (Sebenarnya, ia menggunakan primitif yang juga digunakan StringBuilder)

Namun, jika apa yang Anda lakukan lebih dekat dengan:

string a,b,c,d;
 a = a + b;
 a = a + c;
 a = a + d;

Maka Anda perlu secara eksplisit menggunakan StringBuilder. .Net tidak secara otomatis membuat StringBuilder di sini, karena tidak ada gunanya. Di akhir setiap baris, "a" harus berupa string (tidak dapat diubah), sehingga harus membuat dan membuang StringBuilder di setiap baris. Untuk kecepatan, Anda harus menggunakan StringBuilder yang sama sampai Anda selesai membangun:

string a,b,c,d;
StringBuilder e = new StringBuilder();
 e.Append(b);
 e.Append(c);
 e.Append(d);
 a = e.ToString();
54
James Curran

StringBuilder lebih disukai IF Anda melakukan banyak loop, atau fork dalam kode pass Anda ... namun, untuk kinerja PURE, jika Anda dapat pergi dengan SINGLE = deklarasi string, maka itu jauh lebih performant.

Sebagai contoh:

string myString = "Some stuff" + var1 + " more stuff"
                  + var2 + " other stuff" .... etc... etc...;

lebih berkinerja daripada

StringBuilder sb = new StringBuilder();
sb.Append("Some Stuff");
sb.Append(var1);
sb.Append(" more stuff");
sb.Append(var2);
sb.Append("other stuff");
// etc.. etc.. etc..

Dalam hal ini, StringBuild dapat dianggap lebih dapat dipertahankan, tetapi tidak lebih berkinerja daripada deklarasi string tunggal.

9 kali dari 10 meskipun ... gunakan pembangun string.

Di samping catatan: string + var juga lebih performant daripada pendekatan string.Format (umumnya) yang menggunakan StringBuilder secara internal (ketika ragu ... periksa reflektor!)

28
calebjenkins

Penghitungan ini menunjukkan bahwa penyatuan rutin lebih cepat ketika menggabungkan 3 atau lebih sedikit string.

http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/

StringBuilder dapat membuat peningkatan yang sangat signifikan dalam penggunaan memori, terutama dalam kasus Anda menambahkan 500 string bersama.

Perhatikan contoh berikut:

string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
    buffer += i.ToString();
}
return buffer;

Apa yang terjadi dalam memori? String berikut ini dibuat:

1 - "The numbers are: "
2 - "0"
3 - "The numbers are: 0"
4 - "1"
5 - "The numbers are: 01"
6 - "2"
7 - "The numbers are: 012"
8 - "3"
9 - "The numbers are: 0123"
10 - "4"
11 - "The numbers are: 01234"
12 - "5"
13 - "The numbers are: 012345"

Dengan menambahkan kelima angka itu di akhir string, kami membuat 13 objek string! Dan 12 dari mereka tidak berguna! Wow!

StringBuilder memperbaiki masalah ini. Ini bukan "string yang bisa berubah-ubah" seperti yang sering kita dengar ( semua string dalam .NET tidak dapat diubah ). Ia bekerja dengan menjaga buffer internal, array char. Memanggil Tambah () atau AppendLine () menambahkan string ke ruang kosong di akhir array char; jika array terlalu kecil, itu menciptakan array baru yang lebih besar, dan menyalin buffer di sana. Jadi, dalam contoh di atas, StringBuilder mungkin hanya perlu satu array untuk memuat semua 5 tambahan ke string - tergantung pada ukuran buffer-nya. Anda bisa memberi tahu StringBuilder seberapa besar buffernya seharusnya ada di konstruktor.

23
Matt Trunnell

Contoh sederhana untuk menunjukkan perbedaan kecepatan ketika menggunakan String concatenation vs StringBuilder:

System.Diagnostics.Stopwatch time = new Stopwatch();
string test = string.Empty;
time.Start();
for (int i = 0; i < 100000; i++)
{
    test += i;
}
time.Stop();
System.Console.WriteLine("Using String concatenation: " + time.ElapsedMilliseconds + " milliseconds");

Hasil:

Menggunakan Rangkaian string: 15423 milidetik

StringBuilder test1 = new StringBuilder();
time.Reset();
time.Start();
for (int i = 0; i < 100000; i++)
{
    test1.Append(i);
}
time.Stop();
System.Console.WriteLine("Using StringBuilder: " + time.ElapsedMilliseconds + " milliseconds");

Hasil:

Menggunakan StringBuilder: 10 milidetik

Akibatnya, iterasi pertama mengambil 15423 ms sedangkan iterasi kedua menggunakan StringBuilder mengambil 10 ms.

Tampaknya bagi saya bahwa menggunakan StringBuilder lebih cepat, jauh lebih cepat.

21
Diizzy

Ya, StringBuilder memberikan kinerja yang lebih baik saat melakukan operasi berulang melalui string. Itu karena semua perubahan dilakukan pada satu instance sehingga dapat menghemat banyak waktu alih-alih membuat instance baru seperti String.

String Vs Stringbuilder

  • String

    1. di bawah namespace System
    2. instance immutable (read-only)
    3. kinerja menurun ketika perubahan nilai terus menerus terjadi
    4. benang aman
  • StringBuilder (string bisa berubah-ubah)

    1. di bawah System.Text namespace
    2. contoh bisa berubah
    3. menunjukkan kinerja yang lebih baik karena perubahan baru dibuat ke instance yang ada

Sangat merekomendasikan artikel mob dotnet: String Vs StringBuilder di C # .

Pertanyaan Stack Overflow terkait: Mutabilitas string ketika string tidak berubah dalam C #? .

12
Shamseer K

StringBuilder mengurangi jumlah alokasi dan penugasan, dengan biaya memori tambahan yang digunakan. Digunakan dengan benar, itu benar-benar dapat menghapus kebutuhan untuk kompiler untuk mengalokasikan string yang lebih besar dan lebih besar lagi dan lagi sampai hasilnya ditemukan.

string result = "";
for(int i = 0; i != N; ++i)
{
   result = result + i.ToString();   // allocates a new string, then assigns it to result, which gets repeated N times
}

vs.

String result;
StringBuilder sb = new StringBuilder(10000);   // create a buffer of 10k
for(int i = 0; i != N; ++i)
{
   sb.Append(i.ToString());          // fill the buffer, resizing if it overflows the buffer
}

result = sb.ToString();   // assigns once
8
moswald

String Vs String Builder:

Hal pertama yang harus Anda ketahui bahwa Di Majelis mana dua kelas ini hidup?

Begitu,

string hadir dalam namespace System.

dan

StringBuilder ada di System.Text namespace.

Untuk pernyataan string :

Anda harus memasukkan namespace System. sesuatu seperti ini. Using System;

dan

Untuk pernyataan StringBuilder :

Anda harus memasukkan namespace System.text. sesuatu seperti ini. Using System.text;

Sekarang Hadir Pertanyaan yang sebenarnya.

Apa perbedaan antara string & StringBuilder ?

Perbedaan utama antara keduanya adalah:

string tidak dapat diubah.

dan

StringBuilder bisa berubah.

Jadi Sekarang mari kita bahas perbedaan antara tidak berubah dan bisa berubah

Dapat diubah: : berarti Dapat diubah.

Tidak Berubah: : berarti Tidak Berubah.

Misalnya:

using System;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // String Example

            string name = "Rehan";
            name = name + "Shah";
            name = name + "RS";
            name = name + "---";
            name = name + "I love to write programs.";

            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah RS --- I love to write programs."
        }
    }
}

Jadi dalam hal ini kita akan mengubah objek yang sama sebanyak 5 kali.

Jadi pertanyaan yang jelas adalah itu! Apa yang sebenarnya terjadi di bawah tenda, ketika kita mengganti string yang sama 5 kali.

Ini Yang Terjadi ketika kita mengganti string yang sama 5 kali.

mari kita lihat gambarnya.

enter image description here

Penjelasan:

Ketika kita pertama kali menginisialisasi variabel ini "nama" menjadi "Rehan" i-e string name = "Rehan" variabel ini dibuat di stack "name" dan menunjuk ke nilai "Rehan" itu. setelah baris ini dieksekusi: "name = name +" Shah ". variabel referensi tidak lagi menunjuk ke objek itu" Rehan "sekarang menunjuk ke" Shah "dan seterusnya.

Jadi string adalah makna yang tidak dapat diubah bahwa begitu kita membuat objek dalam memori kita tidak dapat mengubahnya.

Jadi ketika kita menggabungkan variabel name objek sebelumnya tetap ada di memori dan objek string baru dibuat ...

Jadi dari gambar di atas kita memiliki lima objek, empat objek dibuang mereka tidak digunakan sama sekali. Mereka masih tinggal di memori dan mereka menghitung jumlah memori. "Pengumpul Sampah" bertanggung jawab untuk hal itu sehingga membersihkan sumber daya dari memori.

Jadi dalam kasus string kapan saja ketika kita memanipulasi string berulang-ulang kita memiliki beberapa objek yang dibuat dan tinggal di sana di dalam memori.

Jadi ini adalah kisah string Variable.

Sekarang mari kita lihat ke arah objek StringBuilder. Sebagai Contoh:

using System;
using System.Text;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // StringBuilder Example

            StringBuilder name = new StringBuilder();
            name.Append("Rehan");
            name.Append("Shah");
            name.Append("RS");
            name.Append("---");
            name.Append("I love to write programs.");


            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah Rs --- I love to write programs."
        }
    }
}

Jadi dalam hal ini kita akan mengubah objek yang sama sebanyak 5 kali.

Jadi pertanyaan yang jelas adalah itu! Apa yang sebenarnya terjadi di bawah tenda, ketika kita mengubah StringBuilder yang sama sebanyak 5 kali.

Inilah Yang Terjadi ketika kita mengubah StringBuilder yang sama sebanyak 5 kali.

mari kita lihat gambarnya. enter image description here

Penjelasan: Dalam kasus objek StringBuilder. Anda tidak akan mendapatkan objek baru. Objek yang sama akan berubah dalam memori jadi bahkan jika Anda mengubah objek dan mengatakan 10.000 kali kita masih akan memiliki hanya satu objek stringBuilder.

Anda tidak memiliki banyak objek sampah atau objek stringBuilder non_referensi karena itu dapat diubah. Apakah bisa berubah artinya berubah seiring waktu?

Perbedaan:

  • String hadir di System namespace di mana sebagai Stringbuilder hadir di System.Text namespace.
  • string tidak dapat diubah di mana sebagai StringBuilder adalah mutabe.
7
Rehan Shah

Kinerja operasi penggabungan untuk objek String atau StringBuilder tergantung pada seberapa sering alokasi memori terjadi. Operasi penggabungan String selalu mengalokasikan memori, sedangkan operasi penggabungan StringBuilder hanya mengalokasikan memori jika buffer objek StringBuilder terlalu kecil untuk mengakomodasi data baru. Akibatnya, kelas String lebih disukai untuk operasi penggabungan jika sejumlah objek String yang digabungkan. Dalam hal itu, operasi gabungan individu bahkan dapat digabungkan menjadi satu operasi oleh kompiler. Objek StringBuilder lebih disukai untuk operasi penggabungan jika sejumlah string acak digabungkan; misalnya, jika sebuah loop menyatukan sejumlah string dari input pengguna.

Sumber: MSDN

4
user487069

StringBuilder lebih baik untuk membangun string dari banyak nilai yang tidak konstan.

Jika Anda membangun string dari banyak nilai konstan, seperti beberapa baris nilai dalam dokumen HTML atau XML atau potongan teks lainnya, Anda bisa lolos dengan hanya menambahkan ke string yang sama, karena hampir semua kompiler melakukan "konstanta lipat", proses mengurangi pohon parse ketika Anda memiliki banyak manipulasi konstan (itu juga digunakan ketika Anda menulis sesuatu seperti int minutesPerYear = 24 * 365 * 60). Dan untuk kasus-kasus sederhana dengan nilai-nilai non-konstan yang ditambahkan satu sama lain, kompiler .NET akan mengurangi kode Anda menjadi sesuatu yang mirip dengan apa yang StringBuilder lakukan.

Tetapi ketika append Anda tidak dapat direduksi menjadi sesuatu yang lebih sederhana oleh kompiler, Anda akan menginginkan StringBuilder. Seperti yang ditunjukkan oleh fizch, itu lebih mungkin terjadi di dalam satu lingkaran.

3
JasonTrue
2
Jim G.

Menggunakan string untuk rangkaian dapat menyebabkan kompleksitas runtime pada urutan O(n^2).

Jika Anda menggunakan StringBuilder, ada lebih sedikit penyalinan memori yang harus dilakukan. Dengan StringBuilder(int capacity) Anda dapat meningkatkan kinerja jika Anda dapat memperkirakan seberapa besar String akhir akan menjadi. Bahkan jika Anda tidak tepat, Anda mungkin hanya perlu meningkatkan kapasitas StringBuilder beberapa kali yang dapat membantu kinerja juga.

2
Steve g

Saya telah melihat keuntungan kinerja yang signifikan dari menggunakan pemanggilan metode EnsureCapacity(int capacity) pada instance StringBuilder sebelum menggunakannya untuk penyimpanan string. Saya biasanya menyebutnya pada baris kode setelah instantiation. Ini memiliki efek yang sama seperti jika Anda instantiate StringBuilder seperti ini:

var sb = new StringBuilder(int capacity);

Panggilan ini mengalokasikan memori yang diperlukan sebelumnya, yang menyebabkan alokasi memori lebih sedikit selama beberapa operasi Append(). Anda harus membuat perkiraan berpendidikan tentang berapa banyak memori yang akan Anda butuhkan, tetapi untuk sebagian besar aplikasi ini seharusnya tidak terlalu sulit. Saya biasanya berbuat salah di sisi memori terlalu banyak (kita berbicara 1k atau lebih).

2
Jason Jackson

Saya percaya StringBuilder lebih cepat jika Anda memiliki lebih dari 4 string yang perlu Anda tambahkan bersama. Plus itu dapat melakukan beberapa hal keren seperti AppendLine.

2
Gilligan

Di .NET, StringBuilder masih lebih cepat daripada menambahkan string. Saya cukup yakin bahwa di Jawa, mereka hanya membuat StringBuffer di bawah tenda ketika Anda menambahkan string, jadi sebenarnya tidak ada perbedaan. Saya tidak yakin mengapa mereka belum melakukan ini di. NET.

2
Eric Z Beard

String dan StringBuilder sebenarnya tidak berubah, StringBuilder telah dibangun di buffer yang memungkinkan ukurannya dikelola lebih efisien. Ketika StringBuilder perlu mengubah ukuran adalah ketika dialokasikan kembali di heap. Secara default ukurannya adalah 16 karakter, Anda dapat mengatur ini di konstruktor.

misalnya.

StringBuilder sb = new StringBuilder (50);

1
capgpilk

Lebih jauh dari jawaban sebelumnya, hal pertama yang selalu saya lakukan ketika memikirkan masalah seperti ini adalah membuat aplikasi tes kecil. Di dalam aplikasi ini, lakukan beberapa tes waktu untuk kedua skenario dan lihat sendiri mana yang lebih cepat.

IMHO, menambahkan 500+ entri string harus menggunakan StringBuilder.

1
RichS

Rangkaian string akan dikenakan biaya lebih banyak. Di Jawa, Anda dapat menggunakan StringBuffer atau StringBuilder berdasarkan kebutuhan Anda. Jika Anda ingin implementasi yang disinkronkan, dan utas aman, buka StringBuffer. Ini akan lebih cepat daripada penggabungan String.

Jika Anda tidak membutuhkan implementasi yang disinkronkan atau Utas, buka StringBuilder. Ini akan lebih cepat daripada penggabungan String dan juga lebih cepat dari StringBuffer karena tidak ada overhead sinkronisasi.

1
raffimd

StringBuilder secara signifikan lebih efisien tetapi Anda tidak akan melihat kinerja itu kecuali jika Anda melakukan banyak modifikasi string.

Di bawah ini adalah potongan kode cepat untuk memberikan contoh kinerja. Seperti yang Anda lihat, Anda benar-benar hanya mulai melihat peningkatan kinerja besar ketika Anda masuk ke iterasi besar.

Seperti yang Anda lihat, 200.000 iterasi membutuhkan waktu 22 detik, sedangkan 1 juta iterasi menggunakan StringBuilder hampir instan.

string s = string.Empty;
StringBuilder sb = new StringBuilder();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 50000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 200000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();
Console.WriteLine("Beginning Sb append at " + DateTime.Now.ToString());

for (int i = 0; i <= 1000000; i++)
{
    sb.Append("A");
}
Console.WriteLine("Finished Sb append at " + DateTime.Now.ToString());

Console.ReadLine();

Hasil dari kode di atas:

Beginning String + at 28/01/2013 16:55:40.

String Selesai + pada 28/01/2013 16:55:40.

Beginning String + at 28/01/2013 16:55:40.

Selesai String + pada 28/01/2013 16:56:02.

Awal Sb tambahkan pada 28/01/2013 16:56:02.

Selesai Sb tambahkan pada 28/01/2013 16:56:02.

0
CathalMF

Sebagai aturan umum, jika saya harus menetapkan nilai string lebih dari satu kali, atau jika ada tambahan pada string, maka itu harus menjadi pembangun string. Saya telah melihat aplikasi yang telah saya tulis di masa lalu sebelum belajar tentang pembangun tali yang memiliki cetakan kaki memori besar yang sepertinya terus tumbuh dan berkembang. Mengubah program-program ini untuk menggunakan pembangun string mengurangi penggunaan memori secara signifikan. Sekarang saya bersumpah dengan pembuat string.

0
user13288

Pendekatan saya selalu menggunakan StringBuilder ketika menggabungkan 4 atau lebih string OR Ketika saya tidak tahu bagaimana mungkin akan terjadi penggabungan.

Artikel terkait kinerja bagus ada di sini

0
JohnC

StringBuilder mungkin lebih disukai. Alasannya adalah bahwa ia mengalokasikan lebih banyak ruang daripada yang dibutuhkan saat ini (Anda mengatur jumlah karakter) untuk memberikan ruang bagi penambahan di masa mendatang. Kemudian mereka menambahkan masa depan yang sesuai dengan buffer saat ini tidak memerlukan alokasi memori atau pengumpulan sampah, yang bisa mahal. Secara umum, saya menggunakan StringBuilder untuk concatentation string yang kompleks atau banyak format, kemudian dikonversi ke String normal ketika data selesai, dan saya ingin objek yang tidak dapat diubah lagi.

0
deemer

Jika Anda melakukan banyak penggabungan string, gunakan StringBuilder. Ketika Anda menggabungkan dengan String, Anda membuat String baru setiap kali, menggunakan lebih banyak memori.

Alex

0
Alex Fort