Projelerimizde en çok kullandığımız değişken tipi string olsa gerek. String tipinin reference type ve immutuable olması, projelerde hayli yer alması bizim string değişkenlerle yaptığımız işlemlerde performansa ne kadar dikkat etmemiz gerektiğini gösteriyor. String immutuable bir değişken tipidir, dedik. Bunun anlamı string bir değişkene verdiğimiz değeri (aslında değerin adresini) asla değiştiremeyiz. Bunu basit bir örnekle açıklamaya çalışalım.
|
string test = “Veri”; //Bir takım işler test = “Data”; |
Burada yaptığımız heap’de bir yer ayırıp içine “veri”yi koymaktan ve bu yerin adresini test değişkenine vermekten başka bir şey değil. Daha sonra yapılan ise heap’de bir yer daha ayırıp içine “data”yı koymak ve test değişkenine “data”nın adresini vermek. Yani heap’de aslında iki tane yerimiz var (biri “veri”yi içeriyor diğeri “data”yi) ama test değişkenimiz sadece “data”nın bulunduğu adresi tutuyor. Bu şekilde düşündüğümüzde string üzerinde yaptığımız her yeni atamada aslında içindeki veriyi değil, adresini değiştirmiş oluyoruz ve hafızada (heap’de) belki de farkında olmadan fazladan yer tutuyoruz; ta ki garbage collector (GC) zamanı gelip de “veri” nin adresini tutan herhangi bir değişken bulamayıp temizlediği zamana kadar… Şimdi de bir karşılaştırma örneğine bakalım.
|
string test1 = “veri”; string test2 = “data”; // Bir takım işlemler if (test1.ToUpper() == test2.ToUpper()) { // Bir takım işlemler } |
Proje çıktısının ilgili yerini ILDASM ile inceleyelim:

|
if (string.Compare(test1,test2,true) == 0) { // Bir takım işlemler } |
ILDASM ile proje çıktısının ilgili satırına bakarsak:

Fazladan hafızada yer ayırmalar ve değişken tanımlamalar olmamış. Bu da kodumuzun öncekine göre daha performanslı olmasına ve daha az hafıza kullanılmasına sebep olmuştur. String işlemlerinde sıkça kullandığımız bir başka işlem de birleştirmelerdir. Basit bir örnekle bunu da analiz etmeye çalışalım.
|
string test = “veri1″; //Bir takım işlemler test += ” veri2″; //Bir takım işlemler test += ” veri3″; |

ILDASM çıktısına ve önceki bilgilerimize göre ilk string birleştirmede aslında heapde bir yer ayrılıp içine “veri1 veri2” yazıldığını ve bunun adresini bizim değişkenimizin tuttuğunu görürüz. Benzer şekilde ikinci birleştirme de heap’de “veri1 veri2 veri3” yazan bir yer ayrıldığını ve bunun adresini değişkenimizin tuttuğunu rahatlıkla söyleyebiliriz. (Heap görüntüsü şöyledir: “veri”, veri1 veri2, “veri1 veri2 veri3” Yani hafızada 3 ayrı yer ayrılmıştır.) Yani string değişkenimizin içeriğini aslında değiştiremiyoruz, çünkü kendisi immutuable’dır… Bu duruma alternatif çözüm StringBuilder sınıfı ile gelmektedir:
|
StringBuilder sb = new StringBuilder(); sb.Append(“veri1″); //Bir takım işlemler sb.Append(“veri2″); //Bir takım işlemler sb.Append(“veri3″); |
Aslında her zaman StringBuilder sınıfını kullanmak istenen performansı vermeyecektir. Bu sebeple String birleştirme işlemi belirli bir sayıda ise + veya concat metodunu kullanmak daha faydalı iken, belirsiz ve fazla sayıda string birleştirmeler de StringBuilder sınıfını kullanmak daha iyi olacaktır. Bu tavsiyeyi MSDN’de de görüyoruz:
“The String class is preferable for a concatenation operation if a fixed number of String objects are concatenated. In that case, the individual concatenation operations might even be combined into a single operation by the compiler. A StringBuilder object is preferable for a concatenation operation if an arbitrary number of strings are concatenated; for example, if a loop concatenates a random number of strings of user input.”
Projelerimizin minimum kaynak tüketimi ile maksimum performansta çalışmalarını isteriz. Burada da buna nasıl katkı sağlayacağımızı birkaç string işlemi üzerinde incelemeye çalıştık. Belki onlarca satırdan kazanacağımız birkaç ms ve hafızadan tasarruf edebileceğimiz birkaç byte çok fazla bir fark ettirmeyecektir. Ancak unutulmamalıdır ki projelerdeki satır sayısı arttıkça ve yaptığımız işlemler daha da karmaşıklaştıkça bu tip küçük şeylerin aslında ne denli önemli olduğu ortaya çıkacaktır. Ayrıca .NET Framework mimarisinin nasıl çalıştığını anlamamıza bir o kadar da yardımcı olacaktır.
Entries (RSS)
May 29th, 2008 at 09:47
Ergün Bey öncellikle makaleniz çok güzel ve yol gösterici fakat .NET ortamında yazılım geliştirmek için geç kalmış olan ben Aşağıdaki şekilde bir uygulama yazdım
******************************************
Dim s, t, a, i, j, b, k, km As Object
Dim kelime As Object
Dim bul, top_Renamed, sec As Object
Dim secili, sec1 As Object
Dim listkelime, listkelime1 As Object
For t = 1 To Len(Text1.Text)
k = Mid(Text1.Text, 1, 1)
Text1.Text = Replace(Text1.Text, k, “”)
If InStr(1, kelime, k) = 0 Then
kelime = kelime & k
End If
Next t
Text1.Text = kelime
For i = 0 To List1.Items.Count – 1
List1.SelectedIndex = i
top_Renamed = 0
For j = 1 To Len(kelime)
sec = Mid(kelime, j, 1)
bul = InStr(1, List1.Text, sec)
If bul > 0 Then
secili = List1.Text
For s = 1 To Len(kelime)
sec1 = Mid(kelime, s, 1)
secili = Replace(secili, sec1, “”)
Next s
If Len(secili) = 0 Then
top_Renamed = top_Renamed + 1
End If
End If
Next j
listkelime = List1.Text
For t = 1 To Len(List1.Text)
k = Mid(List1.Text, t, 1)
listkelime = Replace(listkelime, k, “”)
If InStr(1, listkelime1, k) = 0 Then
listkelime1 = listkelime1 & k
End If
Next t
If top_Renamed = Len(listkelime1) Then
List2.Items.Add(List1.Text)
End If
listkelime1 = Nothing
Next i
****************************************
Program text deki harflerden oluşan list1 item lerini list 2ye aktarıyor. list1de 65000 civarında kelime barındırdığı için bu işlem çok uzun ve çok zahmetli oluyor anladığım kadarı ile stringbuilder kullanarak bu performans düşüklüğünü gidereblirim şöyle bir ip ucu daha var ki list2 ye eklenecek kelimelerin max uzunluğu 8 karaketr.
sizden istirhamım benim string builder kullanarak yapmaya çalışıpda başarılı olamadığum kod bloğunu string builder kullnılmış halini örneklemeniz, şimdiden teşekkürler