Skip Navigation LinksAnasayfa > Etiketler
C# : Efektif string birleştirme teknikleri Bu yazı .net framework altında etkili string birleştirme yöntemlerine değinmektedir.

Bildiğiniz gibi String değişkeni yazılımlarımızda çok sık kullandığımız veri tiplerimizden bir tanesidir. .Net Framework, System.Text uzayı (namespace) altında barındırdığı sınıflarla (class) string işlemlerine zengin bir destek sağlar. System.Text altındaki sınıfların ayrıntılarına buradan erişebilirsiniz. Mutlaka göz atmanızı tavsiye ediyorum.

Asıl konumuza gelince, bazen yazılımlarımız içerisinde farklı değişkenleri birleştirerek text çıktıları oluşturmamız gerekir. Örneğin, uygulamanızın ürettiği hataları yakalayarak ayrıntılarını bir log dosyasına yazdırmak isteyebilirsiniz. Bu durumda uygulamanız oluşan hatayı yakalamalı ve hata nesnesinin tüm özelliklerini bir metin haline getirerek log dosyasına yazmalıdır. (ayrıca satır satır veri yazma işlemi yapmak da mümkündür; fakat konumuz string birleştirme yöntemlerinin performasını irdelemek olduğu için verinin birleştirilerek yazılması esas alınmıştır.)

Bu yazıda 3 farklı yöntemi inceleyeceğiz ve test edeceğiz.
  • "+" yöntemi ile birleştirme
  • System.Text.StringBuilder sınıfı ile birleştirme
  • System.Collections.Generic.List Generic sınıfı ile birleştirme

1. "+" yöntemi ile birleştirme.

Bu metod string değişkenlerinin + operatörü ile birbiri ardına eklenmesi esasına dayanır.

// iki farklı değişken birleştirilmiştir.
string strFirstName = "Cihan";
string strLastName = "Uçar";
string strName = strFirstName + " " + strLastName;

// aynı değişkene yeni veri eklenmektedir.
string myMessage = "Merhaba ";
myMessage = myMessage + "Dünya. "; // + ile ekleniyor. (Kötünün kötüsü kod.)
myMessage += "Küresel ısınma dünyanın sonu mu?"; // += ile ekleniyor.
myMessage += "Buzullar eriyor, sular yükseliyor.";



Bu yönteme dair görüşümü çok net belirtmek istiyorum: Bu yöntemi unutun, hafızanızdan kazıyın! Bu yöntem string birleştirme işlemleri için son derece kötü ve performans düşürücü bir yöntemdir. Bu yöntemdeki dezavantaj şudur :

String objesi immutable (değişmeyen) bir objedir ve siz her seferinde + ile yeni bir string eklediğinizde mevcut string'iniz yeni bir objeye atanmaktadır. Satır satır açıklamak gerekirse :

string myMessage = "Merhaba ";


myMessage objesi ilk defa yaratıldı ve "Merhaba" değeri atandı.

myMessage = myMessage + "Dünya. ";


Opsss.. myMessage objesi tekrar yaratıldı. myMessage'ın ilk tanımlı değeri ile "Dünya" birleştirilerek myMessage'e atanmıştır. myMessage ikinci kere tanımlandı.

myMessage += "Küresel ısınma dünyanın sonu mu?"; // += ile ekleniyor.


Opsss.. Aynı şekilde myMessage tekrar tanımlandı.

.....

Sonuç olarak her yeni atamada tekrar tekrar yeni bir obje yaratılmaktadır. Ne kadar çok obje yaratılıyorsa o kadar çok kaynak tüketimi gerçekleşir. Bu yöntemin handikapı buradan kaynaklanmaktadır. Küçük çaplı stringleri birleştirirken (ki yine de önermiyorum) bu yöntem nispeten kabul edilebilirken, büyük çaplı string birleştirmelerde asla ama asla kullanılmamalıdır.

2. System.Text.StringBuilder sınıfı ile birleştirme

StringBuilder sınıfı string işlemleri için iyi derecede optimize edilmiş çok kullanışlı bir sınıftır. Bu sınıfı kullanarak oldukça hızlı string manipülasyonları gerçekleştirebiliriz.

Kullanımı şu şekildedir :

using System.Text;
.....
StringBuilder sb = new StringBuilder();
sb.Append("Merhaba ");
sb.Append("Dünya.");
sb.Append("Küresel ısınma dünyanın sonu mu?");
sb.Append("Uydurma metin...");

string myMessage = sb.ToString();


Kullanımı çok basit olan StringBuilder sınıfının ToString metodu ile birleştirilmiş metne erişebilirsiniz.

Bu yöntem çok sayıda string'in birleştirilmesi esnasında kullanılırsa büyük performans sağlar. Genel teori açısından 2 veya daha fazla birleştirme işlemi yapacaksanız önerim bu sınıfı kullanmanız.

3. System.Collections.Generic.List Generic sınıfı ile birleştirme

Generics kavramına ucundan bulaşmamışsanız bu yöntemi boşverin. (Ben bilmiyorum ama kasıcam öğrenicem diyen azimli gençleri şuraya alalım. Azminizi takdir ettiğimi de ayrıca belirtmek isterim.)

Yönteme geçmeden önce .Net framework 2.0 ile gelen özelliklerden birisi olan Generics'e biraz değinmek istiyorum. Generics kod kullanılabilirliğinin arttırılması, performans iyileştirmeleri, koleksiyon sınıfları (collection classes) oluşturulması gibi özellikler sunan bir yapıdır. Teorik olarak anlaşılması zor olmakla birlikte inceleyeceğiniz örnek kodlarla yapıya daha aşina olacağınızı düşünüyorum.

Konumuza dönelim ve string birleştirmelerinin List Generic sınıfı ile nasıl yapıldığını görelim.

using System.Collections.Generic;
........
List<string> list = new List<string>();
list.Add("Merhaba ");
list.Add("Dünya. ");
list.Add("Küresel ısınma dünyanın sonu mu?");
list.Add("Uydurma metin...");

string myMessage = String.Join(String.Empty, list.ToArray());


Örnekte, string tipinde bir generic list oluşturulmuş ve değerler eklenmiştir. ( Aklıma gelmişken System.Collections.Generic.List sınıfının ArrayList sınıfının generic versiyonu olduğunu belirteyim. ) Daha sonra liste değerler array haline dönüştürülerek String.Join metodu ile birleştirilmiştir.

Bu yöntem de oldukça performanslı bir şekilde string birleştirmeye yarar.

Yukarıdaki metotları test etmek için ufak bir uygulama yazdım. Ekran görüntüsü aşağıdaki gibidir :

form1Thumbnail.gif

Arayüz çok basit ve anlaşılır olduğu için ayrıntılara girmiyorum ama uygulamanın test kriterlerini özellikle açıklamak istiyorum.

errorcd.gif
Yazının başında belirttiğim örneği canlandırabilmek için yandaki hata sınıfını yazdım. (ErrorHandler.cs) Şüphesiz bu sınıf gerçek bir hata yakalama sınıfı olmaktan öte test amaçlı yazılmış basit bir sınıftır.

Uygulama kodunu incelerseniz property'lerin varsayılan değerleri olduğunu göreceksiniz. Bunu sadece kolay test verisi üretmek adına yaptım.

Yöntemi test etmek için ilgili butona tıkladığınızda yeni bir ErrorHandler objesi yaratılmakta ve o yöntemi kullanarak ErrorHandler property'leri birleştirilerek tek bir string oluşturulmaktadır. (log dosyası yazılabilir, email atılabilir vs. ) Bu işlem yöntemlerin performans farkı insani açıdan fark edilebilir sürelerde olması için 1000 kere tekrarlanmaktadır.





Yaptığım bir test sonucunu göstermek istiyorum :


test1Thumbnail.gif












Sonuçlar şaka gibi değil mi? Dediğim gibi siz siz olun ilk yöntemi kullanmayın. İkinci ve üçüncü yöntemlerin süreleri çoğu zaman birbirine yakınken ilk yöntem onların yanına asla yaklaşamamaktadır.


Test uygulamasını buradan indirebilirsiniz.

"Hızlı" kalın.

Eklenme Zamanı6/28/2007 3:18 AM   Yorum EkleYorumlar (4)   EtiketlerEtiketler : c# , collections , generics , string , stringbuilder