Arşiv

Etiketlenen yazılar action

C# Performans Analiz Sınıfı

20 Kasım 2011 Yorum yapılmamış

Geliştirmekte olduğumuz uygulamalarda performans analizi yapmak için genellikle Stopwatch sınıfını kullanırız.

Aşağıdaki sınıf’ı kullanarak uygulamanın her method‘unu kolay analiz edebiliriz;

public class PerformansAnaliz
{
	public TimeSpan ToplamSure { get; private set; }
	public TimeSpan OrtalamaSure { get; private set; }

	public static PerformansAnaliz Yeni()
	{
		return new PerformansAnaliz();
	}

	public void Olcumle(Action Method, int TekrarAdet = 1)
	{
		var sw = Stopwatch.StartNew();
		for (int iLoop = 0; iLoop < TekrarAdet; iLoop++)
		{
			Method();
		}
		sw.Stop();
		OrtalamaSure = new TimeSpan(sw.Elapsed.Ticks / TekrarAdet);
		ToplamSure = sw.Elapsed;
	}
}

For – ForEach – List.ForEach performans karşılaştırması

31 Ekim 2010 1 yorum

Bir dizinin tüm elemanları üzerinde bir aksiyon gerçekleştirmemiz gerektiğinde, sıklıkla şu üç yoldan birini kullanırız;

  • For döngüsü
  • ForEach Döngüsü
  • List generic sınıfının ForEach extension method’u

Şimdi basit bir örnek ile bu üç yöntemi karşılaştıralım (*);

(* Not : Karşılaştırmalar; Windows7 64bit kurulu, Core2Duo 3.0 GHz ve 4 GB Ram’li bilgisayarımda yapılmıştır. Sadece fikir verme amaçlıdır, farklı durumlarda faklı sonuçlar ile karşılaşılabilir.)

Öncelikle parametre olarak Generic List (List<T>) alan üç tane method yazalım;

private static long ToplamFor(List<int> Liste)
{
	long Sonuc = 0;
	int ListeAdet = Liste.Count;

	for (int iLoop = 0; iLoop < ListeAdet; iLoop++)
		Sonuc += Liste[iLoop];

	return Sonuc;
}

private static long ToplamForEach(List<int> Liste)
{
	long Sonuc = 0;

	foreach (int Rakam in Liste)
		Sonuc += Rakam;

	return Sonuc;
}

private static long ToplamForEachExtension(List<int> Liste)
{
	long Sonuc = 0;

	Liste.ForEach(Rakam => Sonuc += Rakam);

	return Sonuc;
}

Aynı testi 10 defa gerçekleştirip, ortalamasını alacak bir test fonksiyonu yazalım. Yazacağımız fonksiyonu test listesinde olacak eleman adedini parametre olarak alacak;

private static void Testler(int ListeElemanAdet)
{
	List<int> ForSureler = new List<int>();
	List<int> ForEachSureler = new List<int>();
	List<int> ForEachExtensionSureler = new List<int>();

	List<int> TestVerisi = Enumerable.Range(0, ListeElemanAdet).ToList();

	Stopwatch sw = new Stopwatch();

	for (int iLoop = 0; iLoop < 10; iLoop++)
	{
		sw.Restart();
		ToplamFor(TestVerisi);
		sw.Stop();
		ForSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEach(TestVerisi);
		sw.Stop();
		ForEachSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEachExtension(TestVerisi);
		sw.Stop();
		ForEachExtensionSureler.Add(sw.ElapsedTicks);
	}

	Console.WriteLine("For Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForSureler.Average());

	Console.WriteLine("ForEach Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForEachSureler.Average());

	Console.WriteLine("ForEach Extension ({0} Eleman) : {1}", ListeElemanAdet, ForEachExtensionSureler.Average());
}

Artık uygulamamızın test fonksiyonunu kullanacak son kod parçasını yazabiliriz;

public static void Main(string[] args)
{
	Console.WriteLine("Test Başladı");

	Testler(1000);
	Testler(5000);
	Testler(10000);
	Testler(50000);
	Testler(100000);
	Testler(500000);
	Testler(1000000);
	Testler(5000000);
	Testler(10000000);
	Testler(50000000);

	Console.WriteLine("Test Bitti");

	Console.ReadLine();
}

Bakalım yaptığımız testler nasıl sonuç vermiş;

For - ForEach - ForEach extension Performans Karşılaştırması / Ekran Görüntüsü

Sonuçlardan aşağıdaki tabloyu çıkarttım;

Test Verisi For ForEach ForEach Extension
1.000 71,1 121,5 79,7
5.000 34,3 92,2 55,6
10.000 70,0 185,1 110,4
50.000 349,3 918,4 568,3
100.000 715,2 1.902,7 1.159,0
500.000 3.583,3 9.379,3 5.600,0
1.000.000 7.260,4 18.877,9 11.242,8
5.000.000 37.927,2 96.096,9 57.845,4
10.000.000 74.553,5 192.621,6 115.559,6
50.000.000 371.698,1 956.394,4 572.776,7

İlk olarak 50.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000 elemana kadar inceleme

Son olarak 50.000.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000.000 elemana kadar inceleme

Bu kodda ne yanlış var? – 7

31 Ekim 2010 4 yorum

Aşağıdaki kod sayesinde ekrana, listedeki isimleri küçük harflerle yazdırmak istiyorsunuz.

using System;
using System.Collections.Generic;

public class EkranaYazdir
{
	public static void Main()
	{
		List<string> Kisiler = new List<string>();

		Kisiler.Add("AHMET");
		Kisiler.Add("MEHMET");
		Kisiler.Add("AYŞE");
		Kisiler.Add("FATMA");

		/// string elemanları küçük harfe çevir
		Kisiler.ForEach(
			delegate(string k)
			{
				k = k.ToLower();
			}
		);

		/// console'a yaz
		Kisiler.ForEach(
			delegate(string s)
			{
				Console.WriteLine(s);
			}
		);
	}
}

MSDN‘de List<T>.ForEach() sayfasında;

Orjinali; Performs the specified action on each element of the List.

Türkçesi; Listedeki her eleman için belirlenmiş action çalıştırır.

yazısını okudunuz, ve kodun doğru çalışmasını bekliyorsunuz.

Fakat istediğiniz gibi çalışmıyor, sizce problem nedir ve nasıl düzeltilebilir?

Birkaç Faydalı Extension Method

30 Ocak 2010 Yorum yapılmamış

C# 3.0 ile gelen Extension Method desteğini çok kullanışlı bulduğum için, kendi uygulamalarımda kullanmaya çalışıyorum. Bu yazımda faydalı bulduğum birkaç Extension Method‘u toplamaya çalıştım.

Metni Encrypt – Decrypt Eden Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string Encrypt(this string stringToEncrypt, string key)
		{
			if (string.IsNullOrEmpty(stringToEncrypt))
				throw new ArgumentException("Boş metin şifrelenemez");
			if (string.IsNullOrEmpty(key))
				throw new ArgumentException("Şifreleme için anahtar vermelisiniz");

			CspParameters cspp = new CspParameters();
			cspp.KeyContainerName = key;

			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
			rsa.PersistKeyInCsp = true;

			byte[] bytes = rsa.Encrypt(UTF8Encoding.UTF8.GetBytes(stringToEncrypt), true);

			return BitConverter.ToString(bytes);
		}

		public static string Decrypt(this string stringToDecrypt, string key)
		{
			if (string.IsNullOrEmpty(stringToDecrypt))
				throw new ArgumentException("Beş metnin şifresi çözülemez");
			if (string.IsNullOrEmpty(key))
				throw new ArgumentException("Şifre çözme için anahtar vermelisiniz");
			string result = null;
			try
			{
				CspParameters cspp = new CspParameters();
				cspp.KeyContainerName = key;

				RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
				rsa.PersistKeyInCsp = true;

				string[] decryptArray = stringToDecrypt.Split("-");
				byte[] decryptByteArray = Array.ConvertAll<string, byte>(decryptArray, (s => Convert.ToByte(byte.Parse(s, NumberStyles.HexNumber))));
				byte[] bytes = rsa.Decrypt(decryptByteArray, true);

				result = UTF8Encoding.UTF8.GetString(bytes);
			}
			catch()
			{
			}
			return result;
		}
	}
}

Örnek kullanım;

string metin = "My Secret";
string sifrelenmis = metin.Encrypt("sifreleyici");
string sifresicozulmus = sifrelenmis.Decrypt("sifreleyici");

Listeler üzerinde Foreach Yapan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static void ForEach<T>(this IEnumerable<T> kaynak, Action<T> islem)
		{
			foreach (var item in kaynak)
				islem(item);
		}
	}
}

Örnek kullanım;

List<string> isimler = new List<string> { "engin", "polat", "ahmet", "mehmet", "murat" };
isimler.ForEach(isim => MessageBox.Show(isim));

İnternet Adresi Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsValidUrl(this string text)
		{
			Regex r = new Regex(@"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
			return r.IsMatch(text);
		}
	}
}

Örnek kullanım;

string Adres = "http://www.enginpolat.com";
bool AdresDogru = Adres.IsValidUrl();

Email Adresi Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsValidEmail(this string text)
		{
			Regex r = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
			return r.IsMatch(text);
		}
	}
}

Örnek kullanım;

string Adres = "test@test.com";
bool AdresDogru = Adres.IsValidEmail();

Klasör Oluşturan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static void CreateDirectory(this DirectoryInfo dirInfo)
		{
			if (dirInfo.Parent != null)
				CreateDirectory(dirInfo.Parent);
			if (!dirInfo.Exists)
				dirInfo.Create();
		}
	}
}

Örnek kullanım;

var dir = new DirectoryInfo(@"C:\temp\bir\iki\uc");
dir.CreateDirectory();

Tarihin Haftasonuna Geldiğini Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsWeekend(this DateTime value)
		{
			return (value.DayOfWeek == DayOfWeek.Sunday || value.DayOfWeek == DayOfWeek.Saturday);
		}
	}
}

Örnek kullanım;

for (DateTime date = BaslangicTarih; date <= BitisTarih; date = date.AddDays(1))
{
	if (date.IsWeekend())
		continue;
	/// Tatil değil, yapılacak işler yapılır.
}

Object türünden JSON’a, JSON’dan Object Türüne Çeviren Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string ToJson(this object obj)
		{
			JavaScriptSerializer serializer = new JavaScriptSerializer();
			return serializer.Serialize(obj);
		}

		public static T FromJson<T>(this object obj)
		{
			JavaScriptSerializer serializer = new JavaScriptSerializer();
			return serializer.Deserialize<T>(obj as string);
		}
	}
}

Örnek kullanım;

Personel Engin = new Personel("Engin Polat", 5000);
string json = Engin.ToJson();
Engin = null;
Engin = s.FromJson<Personel>();

Tarihten Yaş Hesaplayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static int Age(this DateTime tarih)
		{
			DateTime now = DateTime.Now;
			int yas = now.Year - tarih.Year;
			if (now < tarih.AddYears(yas))
				yas--;
			return yas;
		}
	}
}

Örnek kullanım;

DateTime AhmetDogumGunu = new DateTime(1979, 05, 07);
int Yas = AhmetDogumGunu.Age();

Ayın İlk Gününü – Ayın Son Gününü Bulan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static DateTime FirstDayOfMonth(this DateTime date)
		{
			return new DateTime(date.Year, date.Month, 1);
		}

		public static DateTime LastDayOfMonth(this DateTime date)
		{
			return new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddDays(-1);
		}
	}
}

Örnek kullanım;

DateTime Simdi = DateTime.Now;
MessageBox.Show("Ayın ilk günü: " + Simdi.FirstDayOfMonth().ToShortDateString());
MessageBox.Show("Ayın son günü: " + Simdi.LastDayOfMonth().ToShortDateString());

Dosyanın MD5 Değerini Hesaplayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string GetMD5(this string filename)
		{
			string result = string.Empty;

			try
			{
				MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
				FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
				byte[] arrByteHashValue = md5Provider.ComputeHash(fileStream);
				fileStream.Close();

				string hashData = BitConverter.ToString(arrByteHashValue).Replace("-", "");
				result = hashData;
			}
			catch()
			{
			}
			return result.ToLower();
		}
	}
}

Örnek kullanım;

string Dosya = @"C:\Temp\DosyaAdi.txt";
MessageBox.Show(Dosya + " dosyasının MD5 değeri: " + Dosya.GetMD5());