18 Nisan 2009 Cumartesi

String vs StringBuilder

Şirkette şu an üstünde çalışmakta olduğumuz güzel düşünülmüş, bir arkadaşın ortaya koyduğu bir generic simülatör projesi var. Projenin ayrıntılarına girmem mümkün değil ancak çalışma prensibi değişken, fonksiyon, class, dll'ler, protokoller gibi kodu oluşturan öğelerin bir kullanıcı arayüzü yardımıyla xml dosyalarına yazılması ve ardından bu xml dosyalarının parse işlemiyle koda dönüştürülmesi şeklinde. Tabi simülatöre eklenen her öğe oluşturulan kodun büyümesine sebep oluyor, ve böylece gerçekten çok kapsamlı ve yetenekli bir simülatör oluşturulduğunda binlerce satır koda erişilmiş oluyor.

İşte bu noktada kodun oluşturulma süresi büyük önem kazanıyor. "Generate" dedikten sonra yavaş yavaş ilerleyen bir progress bar görüntüsünü hiç kimse sevmez. Üreteci hazırlayan arkadaşın da hoşuna gitmemiş olmalı ki performans iyileştirmesine gitmeye karar verdi. Benim de String ve StringBuilder arasındaki farkı öğrenmem onun sayesindedir. Kodu geliştirip çalıştırdığında göz açıp kapayıncaya kadar kodun üretildiğini görünce merak ettim, String yerine StringBuilder kullandım hepsi bu dedi. Bunun üzerine taa üniversitedeyken "String class'ı var ya nasıl olsa, bunların hepsini yapıyor, StringBuilder gibi daha komplex bir şeyi birşeyi hatırlamama neden gerek olsun ki" şeklindeki tembel düşüncemi hatırlayıp utandım, ve merakımı gidermeye karar verdim.

Şimdi işin hikaye kısmını geçip konuya girelim:
Kaynağım CodeProject. Konuyla ilgili en sade ve öz anlatımı burda buldum. Alois Kraus arkadaş iyi iş çıkarmış. Özetle durum şu:
String'in değişken olmayan(immutable) bir yapısı var, o yüzden herhangi bir ekleme çıkarma vs. işlemi yaptığınızda yeni bir obje üretilmekte. StringBuilder ise değişken(mutable) bir yapıda. Ama tabi bu her zaman iyi anlamına gelmiyor. Kraus da diyor ki, assembler kodunu görmeden hangisinin daha iyi performans vereceğine karar vermeyin.
Assemblerla uğraşmak istemeyenler için(sanırım çoğumuz bu kategorideyiz) Kraus bir performans testi yapmış. Insert, Remove, Replace, Format, Append, Join gibi fonksiyonların zaman ve uygulanan operasyon sayısı grafiğini çıkaracak testler hazırlamış. Grafikler aynen şunlar:





Bu tabloları yorumlayacak olursak en iyi performansı veren fonksiyonlar şunlar:
Insert: StringBuilder.Insert, 2'den az ise String.Insert
Remove: StringBuilder.Remover, 2'den az ise String.Remove
Replace: String.Replace
Format: StringBuilder.AppendFormat, 5'ten az ise String.Format
Concatenation: String.Join, 2 ise String+

Hiç yorum yok:

Yorum Gönder