Metin(String) Ýþlemlerinde Performansý Artýrmak
 

Programlama yaparken sýk sýk metinsel iþlemler yapmak durumunda kalýrýz.

Bir metni baþka bir metinle birleþtiririz...

Büyükçe bir metnin  içerisinden bir bölümünü alýrýz...

Ýki metni birbiriyle karþýlaþtýrýrýz...

....

Bu liste böylece uzar gider. Metinsel iþlemler denilince akla gelen ilk þey metin birleþtirme iþlemidir. “Bir metnin bir diðerine eklenmesi.” Ýþ metinle ilgili olduðunda bu iþi gerçekleþtirmek için C# ta ilk akla gelen veri tipi “string” dir. “System.String” sýnýfýný (class) temsil eden string bir referans türüdür. Ancak biraz farklý bir referans türüdür. Yapý olarak “immutable”, yani deðiþmezdir/sabittir ve bu yüzden bir kez yapýlandýrýldýktan sonra içeriði deðiþtirilemez. Ýþte bu yapýdan dolayýdýr ki bir string deðiþkene ancak bir kez deðer atayabilirsiniz.

Peki ya aþaðýdaki kod?

string metin="Merhaba";

metin=metin + " Dünya!"; // metin=”Merhaba dünya!”

String bir referans türü olduðu için bellekteki öbek (heap) bölgesinde yaratýlýr ve içeriðine “Merhaba” yüklenir. Öbekteki bu nesneye kodun eriþebilmesi için gerekli adres bilgisi ise belleðin yýðýn (stack) bölgesinde yaratýlan “metin” deðiþkenine yazýlýr. Yani referans türlerde deðiþken nesneyi deðil, nesnenin adresini tutar.

Þimdi ikinci satýra bakalým. Birinci satýrda, metin deðiþkeninin temsil ettiði string nesnesine “birinci string nesnesi” diyelim. Ýkinci satýrdaki kod iþlendiðinde “birinci string nesnesi” üzerine yeni deðer ekelenemeyeceðinden, öbekte ikinci bir string nesnesi türetiliyor ve iþlem sonucu, yani “Merhaba Dünya!” bu ikinci string nesnesine yükleniyor.

Ve kilit nokta!

“metin” deðiþkeni ikinci satýrdaki kodun sonunda artýk “birinci string nesnesi”nin deðil, “ikinci string nesnesi”nin adresini taþýmaya baþlýyor. Yani artýk “birinci string nesnesi” tamamen eriþilemez oluyor ve “Çöp Toplayýcý” (Garbage Collector) devreye girip belleði temizleyene kadar bellekte yer tutmaya devam ediyor.

Ýþte “string” veri tipinin bu yapýsý nedeniyle metinsel iþlemlerde daha iyi performans saðlamak amacýyla System.Text isim alaný içine bulunan “StringBuilder” sýnýfý kullanýlmaktadýr.

Algoritmaya baðlý olarak deðiþmekle birlikte, StringBuilder sýnýfýnýn çok çok daha hýzlý olduðu söylenebilir.

'string' veri tipi kullanilarak metin birlestirme.....

Baslangiç : 24.11.2003 20:31:06

Bitis : 24.11.2003 20:31:08

Toplam süre : 2193,1536 milisaniye

'StringBuilder' sinifi kullanilarak metin birlestirme.....

Baslangiç : 24.11.2003 20:31:08

Bitis : 24.11.2003 20:31:08

Toplam süre : 20,0288 milisaniye

Uygulamaya sonlandirmak içim [Enter] tusuna basin.

Aþaðýdaki örnek kod ve yukarýdaki ekran görüntüsü, metin birleþtirme iþlemlerinde gerçekten çok iyi performans gösteren StringBuilder sýnýfýnýn, string ile karþýlaþtýrýldýðý bir Console uygulamasýdýr.

static void Main(string[] args)
{

    // Degisken tanimlari

    string str="";

    System.Text.StringBuilder sb=new System.Text.StringBuilder();

    DateTime start; // islemin baslangiç ani

    DateTime end; // islemin bitis ani

    TimeSpan sure; // islemin toplam süresi

    // string veri tipiyle metin birlestirme islemi.....

    Console.WriteLine("'string' veri tipi kullanilarak metin birlestirme.....");

    start=DateTime.Now; // islemin baslangiç zamani

    Console.WriteLine("Baslangiç :\t" + start.ToString());

    // Metin birlestirme islemi.....

    for(int i=0;i<10000;i++)

    {

        str +=i.ToString();

    }

    end=DateTime.Now; // islemin bitis zamani

    Console.WriteLine("Bitis :\t\t" + end.ToString());

    sure=end.Subtract(start); // geçen süre hesaplaniyor..

    Console.WriteLine("Toplam süre :\t" + sure.TotalMilliseconds + " milisaniye");

    //-------------------------------------------------------

    Console.WriteLine();

    // StringBuilder sinifiyla metin birlestirme islemi.....

    Console.WriteLine("'StringBuilder' sinifi kullanilarak metin birlestirme.....");

    start=DateTime.Now; // islemin baslangiç zamani

    Console.WriteLine("Baslangiç :\t" + start.ToString());

    // Metin birlestirme islemi.....

    for(int i=0;i<10000;i++)

    {

        sb.Append(i.ToString());

    }

    end=DateTime.Now; // islemin bitis zamani

    Console.WriteLine("Bitis :\t\t" + end.ToString());

    sure=end.Subtract(start);// geçen süre hesaplaniyor..

    Console.WriteLine("Toplam süre :\t" + sure.TotalMilliseconds + " milisaniye");

    //-------------------------------------------------------

    Console.WriteLine();

    Console.WriteLine("Uygulamaya sonlandirmak içim [Enter] tusuna basin.");

    Console.ReadLine();
}