inicio mail me! sindicaci;ón

Gereksiz exceptionlardan kaçınmak için TryParse metodunu kullanın

Parse metodu, başarısız olması halinde ArgumentNullException, FormatException veya OverflowException oluşturmaktadır. Çoğu zaman oluşan bu exceptionlara ihtiyaç duymayız. Bu gibi durumlarda ihtiyaç duymadığımız exceptionlar, uygulamalarımızın performansını olumsuz etkilemektedir.
TryParse metodu, dönüştürme işleminin başarısız olması halinde exception oluşturmak yerine false değerini döner.

Aşağıdaki kod bloğunun çalışması 21,217 Saniye sürmektedir.

DateTime startTime = DateTime.UtcNow;

for (int i = 0; i < 5000; i++)
{
try
{
int n = Int32.Parse(“test”);
}
catch { }
}

DateTime endTime = DateTime.UtcNow;

Ancak bu kod bloğunu aşağıdaki şekilde değiştirdiğimiz zaman işlem süresi 0,1 saniyeye düşmektedir.

DateTime startTime = DateTime.UtcNow;

for (int i = 0; i < 5000; i++)
{
try
{
int n;
Int32.TryParse(“test”, out n);
}
catch { }
}

DateTime endTime = DateTime.UtcNow;

Gördüğünüz gibi gereksiz exceptionların uygulama performansı üzerindeki olumsuz etkisi oldukça büyük.

Ne zaman StringBuilder, ne zaman += Kullanmalıyım?

Çoğu zaman yazılım geliştiricilerin dikkat etmediği, ancak uygulama performansını ciddi oranda etkileyen bir konudur string birleştirme işlemleri. Çoğu zaman += ile bir string değişkenin değerini değiştirmeye çalışan yazılım geliştiriciler, büyük miktarda veri ile çalıştıkları zamanlarda uygulamanın ne kadar yavaş çalıştığından şikayet ederler.

Eğer string birleştirmeyi tek bir ifade içinde gerçekleştiriyorsanız (bir başka değişle, birleştirilecek string değişkenlerin sayısı belirliyse), String.Concat metodu çalıştırılır. Bu durumda performans kaybı yaşamayız çünkü gereksiz geçici nesneler oluşturulmaz. Dolayısıyla bu senaryoda bu çözüm oldukça efektiftir.
Ancak birleştirilecek string değişkenlerin sayısı belirli değilse, örneğin string birleştirme işlemini bir döngü içinde gerçekleştiriyorsanız, += ifadesi ile string birleştirme yapmak uygulamanız için ciddi performans kaybı anlamına gelecektir.

StringBuilder sınıfı 16′lık varsayılan kapasite ile oluşturulur. Eğer bu değerden daha fazla değer eklemek isterseniz, StringBuilder sınıfı sizin için o anki boyutunun 2 katı oranında bir alanı rezerve eder. Ancak bu senaryoda += ifadesini kullanırsanız, döngünün her adımında bir geçici nesne oluşturulacağından işlem süresi artacaktır.

Aşağıdaki kodu çalıştırdığımız zaman işlem süresi 5,282 Saniye olarak gerçekleşiyor.

string result = String.Empty;
DateTime startTime = DateTime.UtcNow;

for (int i = 0; i < 35000; i++)
{
result += r.Next(10000, 99999);
}
DateTime endTime = DateTime.UtcNow;

Ancak kodu aşağıdaki şekilde değiştirdiğim zaman işlem süresi 0,11 Saniyeye düşüyor.

StringBuilder sb = new StringBuilder();
string result = String.Empty;

DateTime
startTime = DateTime.UtcNow;
for (int i = 0; i < 35000; i++)
{
sb.Append(r.Next(10000, 99999));
}
result = sb.ToString();
DateTime endTime = DateTime.UtcNow;

Sanıyorum bu basit örnek bile, bu basit ayrıntının büyük ölçekli projelerde ne kadar büyük bir performans farklı yaratacağını göstermek için yeterli olmuştur.

DateTime.Now yerine DateTime.UtcNow özelliğini kullanın

DateTime karşılaştırmalarında veya hesaplamalarında, DateTime.Now özelliği yerine DateTime.UtcNow özelliğini kullanmanın performans üzerinde olumlu etkisi olacaktır. Bunun nedeni, DateTime.UtcNow özelliğinin işlemleri culture-neutral gerçekleştiriyor olmasıdır.

Örneğin aşağıdaki kod bloğunda DateTime.Now özelliğini kullandığım zaman işlem 4,998 saniyede tamamlanıyor.

DateTime startTime = DateTime.UtcNow;

for (int i = 0; i < 10000000; i++)
{
DateTime result = DateTime.Now;
}

DateTime
endTime = DateTime.UtcNow;

Ancak for döngüsünün içindeki DateTime.Now ifadesini DateTime.Now ile değiştirdiğim aşağıdaki kod blığunun çalışması 0,301 saniyede tamamlanıyor.

DateTime startTime = DateTime.UtcNow;

for (int i = 0; i < 10000000; i++)
{
DateTime result = DateTime.UtcNow;
}

DateTime endTime = DateTime.UtcNow;

Büyük ölçekli projelerde bu özelliğin oldukça sık kullanıldığını dikkate alacak olursak, toplamda uygulama performansını ciddi oranda etkileyebilecek bir ipucu olarak dikkate alabiliriz.

Not: İşlem süreleri kendi kullandığım 2,4 Ghz Macbook Pro için geçerlidir. Farklı konfigurasyonlarda ve işlem esnasında bilgisayarda çalışan uygulamalara bağlı olarak, işlem sürelerinde değişiklikler olacaktır.

Case Insensitive string karşılaştırma işlemleri için overload edilmiş Compare metodunu kullanın

ToLower metodu geçici string nesneleri oluşturduğu için, Case Insensitive karşılaştırma yaparken, ToLower() metodunu kullanmaktan kaçınmak için Compare metodunu kullanmak uygulama performansını olumlu yönde etkileyecektir.

Aşağıdaki kod, case insensitive karşılaştırma işlemini gerçekleştirmesine karşın, kullanılan ToLower() metodları yüzünden geçici string nesneleri oluşturarak uygulama performansını olumsuz yönde etkilemektedir:

String str=“KADİR SÜMERKENT”;
String str2 = “Kadir Smerkent”;

if (str.ToLower()==str2.ToLower())
{
// işlemler
}

Bu işlemi daha yüksek performanslı bir şekilde gerçekleştirmek için aşağıdaki kodu kullanabiliriz:

String.Compare(str, str2, true);

Uzun sürecek işlemlerin öncesinde gerek duyulmayan değişkenleri null olarak set edin

Uzun sürecek veya yoğun kaynak kullanacak işlemlerin öncesinde gerek duyulmayan değişkenlerin null olarak set edilmesi, bu değişkenlerin null olarak set edilmesi, garbage collector tarafından toplanabilmelerini sağlayacağından performans arttırıcı bir önlem olacaktır.

Bu zorunlu bir uygulama olmamakla birlikte, aşağıdaki durumlarda kullanılması, performans üzerinde olumlu yönde etkili olacaktır:
* Classınızın veya farklı bir class içindeki static bir değişkene  artık ihtiyacınız yoksa bunları null olarak set edin
* Yorucu metodu çalıştırmadan önce dispose edebileceğiniz nesneler varsa, bunları null olarak set edin

Aşağıdaki kod şu ana kadar bahsettiğim konuları örneklemekte ve uzun sürecek bir işlem öncesi gereksiz değişkenlerin değerlerini null olarak set etmektedir:

class

MyClass
{
private string str1;
private string str2;

 

void DoSomeProcessing()
{
str1= GetResult();
str2= GetOtherResult();
}

void MakeDBCall()
{
PrepareForDBCall(str1,str2);

str1=null;
str2=null;

LongRunningDbCall();
}
}

Aynı zamanda, JIT compiler bir değişkenin artık kullanılmadığını ve ona ihtiyaç olmadığını tespit edebildiği için, local değişkenlerin null olarak set edilmesine ihtiyaç yoktur. Aşağıdaki kod bloğu, local değişkenlerin kullanımını örneklemektedir:

void f1()
{
String strVar;
strVar = “abc”;

// Local değikeni null olarak
// set etmekten kann
strVar = null;
}

Daha etkin kaynak yönetimi için finally bloğunu kullanın

Özellikle aşağıdaki nesne ve yapılarla çalışırken daha etkin kaynak yönetimi için finally bloğunu kullanın.
* veritabanı bağlantıları
* dosyalar
* mesaj kuyrukları
* text reader ve writer’lar
* binary reader ve writer’lar
* crypto stream
* simetrik, asimetrik ve hash algoritmaları
* timer ve threading kullanımında wait handle
* xml reader ve writer

Örneğin bir veritabanı bağlantısının her koşulda (işlem başarılı olsa da, hata oluşsa da) kapanmasını sağlamak için aşağıdaki kodu kullanabilirsiniz;

SqlConnection conn = new SqlConnection();

try
{
conn.Open();
//işlemler
conn.Close();
}
finally
{
if (conn.State==ConnectionState.Open)
conn.Close();
}

Close metodunun hem try hem finally bloğunda çağrıldığına dikkat edin. Close metodun, inally bloğunda da yer aldığı için Try bloğunda kullanmamamız herhangi bir soruna yol açmayacaktı ancak kaynakları mümkün olduğunca erken serbest bırakabilmek için bu blokta da kullandık. Finally bloğunda yer alan Close metodu ise, try bloğunun herhangi bir nedenle kesilmesi sonucunda çalışarak bağlantımızın her koşulda kapanmasını garanti altına alacaktır.

Dosya Okuma İşlemlerinde ReadAllLines, ReadAllText ve ReadAllBytes Metodlarını Kullanın

Bir dosyadaki tüm verileri okumak için File.ReadAllText, File.ReadAllLines, veya File.ReadAllBytes metodlarını kullanın.
ReadAllText metodu dosyadaki tüm veriyi string olarak, ReadAllLines metodu string array olarak, ReadAllBytes metodu ise byte array olarak okumaktadır ve b metodlar geleneksel okuma rutinine göre daha yüksek performans sunmaktadır. Bu metodlar sayesinde aynı zamanda sık sık unutulan ve sorunlara neden olan dosyaların okuma sonrasında kapatılması sorununu da ortadan kaldırmaktadır (tabi siz asla unutmazsınız :) ).

Kullanımı;
* dosyadaki tüm verileri string olarak okuyarak bir string değişkene atamak için
myVar = File.ReadAllText(filename);

* dosyadaki tüm verileri satır satır okuyarak bir string array’e aktarmak için
string[] myVar = File.ReadAllLines(filename);

* dosyadaki tüm verileri alarak bir byte array’e aktarmak için
byte[] myVar = File.ReadAllBytes(filename);

Örnek
Windows tabanlı bir uygulamada, disk üzerindeki bir dosyayı okuyarak içindeki verileri bir metin kutusuna aktarmak istediğimizi varsayalım.
Yazacağımız kod şöyle olacaktır; using

StreamReaderStringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(filename))
{
while (sr.Peek() >= 0)
{
sb.AppendLine(sr.ReadLine());
}
}
textBox1.Text = sb.ToString();

Ancak bu kod, dosyanın içeriğini satır satır okuyacağı için büyük boyutlu dosyalarda işlem süresi oldukça uzayacaktır.

Bu kodu şu şekilde değiştirerek aynı işlemi çok daha hızlı bir şekilde gerçekleştirmemiz mümkündür;

textBox1.Text = File.ReadAllText(filename);

Bu kodun arkaplanına bakacak olursak; File.ReadAllText metodu System.IO.File içinde yer alan static bir metoddur. Bizim kullandığımız tek parametreli overload, kendi içinde ReadAllText(filename, Encoding.UTF8) şeklinde bir çağrı yapmaktadır.

Encoding parametresi alan overload’ın kodları ise şu şekildedir;

public static string ReadAllText(string path, Encoding encoding)
{
using (StreamReader reader = new StreamReader(path, encoding))
{
return reader.ReadToEnd();
}
}

Hangi Collection Türünü Ne Zaman Kullanmalıyız?

Uygulamalarımızda en sık kullandığımız yapılardan biri şüphesiz collectionlar. Kullandığımız collectionların, uygulamalarımızın performansı üzerinde büyük bir etkisi olduğu için, doğru yerde doğru collection türünü kullanıyor olmamız çok önemli.
Collection seçiminde boyut, collection içinde tutulacak verinin türü ve gereksinim duyulan fonksiyonlar en önemli kriterlerimizdir.

Eğer collection içindeki verileri sıralayacaksanız;
* DataGrid benzeri bir kontrolde, sıralanmış verileri read-only olarak data source olarak kullanacaksanız arraylist kullanın.
* Çok sık güncellenmeyecek olarak verilerin sıralamak için SortedList kullanın.
* String değerleri sıralamak için NameValueCollection kullanın.
* SortedList nesnesi collectionı oluştururken verileri ön sıralamaya tabi tutar. Bu doğal olarak daha yüksek maliyetli bir oluşturma süreci anlamına gelir ancak mevcut verilerdeki değişiklikler ve listede yapılacak basit eklemeler hızlı bir şekilde collectiona yansıtılır ve sıralama güncellenir. SortedList nesnesi küçük güncellemelere tabi olacak, küçük ölçekli veriler için uygundur.

Collection içinde arama yapacaksanız;
* Bir anahtar/değer çifti ile random arama yapacaksanız HashTable kullanın.
* String türünden veriler üzerinde random arama yapacaksanız StringDictionary kullanın.
* 10dan daha az sayıda veri içinde arama yapacaksanız ListDictionary kullanın.

Collectiondaki nesnelere Index aracılığıyla erişecekseniz;
* Bir anahtar belirterek veri erişimi yapmak için Hashtable, SortedList, ListDictionary ve StringDictionary nesnelerini kullanın.
* Bir anahtar veya sıfır tabanlı bir index değeri belirterek veri erişimi yapmak için NameValueCollection nesnesini kullanın.
* Sıfır tabanlı bir index değeri belirterek veri erişimi yapmak için ArrayList ve StringCollection nesnelerini kullanın.

Class’larınızda Equals metodunu Override Edin

Equals System.Object tarafından sunulan bir metoddur. Equals’ın standart implementasyonunu kullandığınız taktirde, value type’ınıza boxing uygulanarak System.ValueType olarak işlem görecek ve CLR karşılaştırma yapmak için Reflection kullanacaktır. Bu kıyaslama sürecinde gerçekleştirilecek dönüştürmeler ve reflection işlemleri, kıyaslama işleminin maliyetinin artmasına neden olacaktır.

Oluşturduğunuz class’a özel bir Equals implementasyonu, kıyaslamalarda bu maliyeti en aza indirgemenizi sağlayacaktır.

Aşağıdaki kod bloğu, kıyaslama maliyetini en aza indirgemek amacıyla override edilmiş bir Equals metod implementasyonunu örneklemektedir.

public

struct Personel
{
public string Ad;
public double Yas;

public override bool Equals(object item)
{
if (item is Personel) return Equals((Personel)item);  else return false;
}

private bool Equals(Personel obj)
{
return Ad == obj.Ad && Yas == obj.Yas;
}
}

Sharepoint çözümleri ve Visual Studio 2008 Semineri

10 Mayıs 2008 Cumartesi günü Microsoft İstanbul ofisinde gerçekleşecek olan Sharepoint çözümleri ve Visual Studio 2008 Seminerine davetlisiniz…

10 Mayıs 2008 Cumartesi günü Microsoft İstanbul ofisinde ücretsiz olarak gerçekleşecek olan “Sharepoint çözümleri ve Visual Studio 2008 “ seminerine bütün msakademik üyelerini davet ediyoruz. MVP( Most Valuable Professional ) ödülüne sahip Eralp Erat ‘ ın vereceği bu seminerde , döküman yönetimi , iş akış yönetimi ve bunların tam verimlilikle nasıl kullanılabileceği irdelenecektir.

Yer : Microsoft İstanbul Ofisi
Saat : 13.00-17.00
Tarih : 10 Mayıs 2008 Cumartesi