Merhaba arkadaşlar bu yazıya uygun başlık bulamadım çünkü 2-3 şeye birden degiyor olacağız o nedenle Zaman\Performans\Data koydum.Bu makaleyi bayadır yazacaktım ancak bu gün ancak bu kadar makale yazmaya hevesli ve müsait oldum
Bu makalemizde ne yapacağız ? ne anlatacağız ?
Bu makalemde sizlere C# programımızın ne kadar saniyede çalıştığını, data işlemleri esnasında alt yapının önemini , OOP yaparken performans düşürdüğümüz noktalardan bahsedeceğim.
Öncelikle system.Diagnostics namespace altında yer alan Stopwatch’dan bahseceğiz bu sınıf sayesinde programımızın son satırına eklediğimiz TotalMilliseconds methoduyla programımızın ne kadar milisaniyede çalıştığını görebiliyoruz.
Tabiki öncelikle name space alınına bir system.Diagnostics ekliyoruz StopWatch sınıfımızdan bir nesne kuruyoruz daha sonra bu işleme başlıyoruz.
Örneğin 1’den 10’a kadar sayıları yazdıran programımızın ne kadar zamanda çalıştığını gösteren çıktıyı alalım.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Stopwatch s = new Stopwatch();
s.Start();
for (int i = 0; i < 10; i++)
{
Console.Write(i);
}
Console.WriteLine("\n"+s.Elapsed.TotalMilliseconds.ToString());
}
}
}
Porgramımızın ekran çıktısı şu şekilde olacaktır>
0123456789
1,0294
Stopwatch sınıfından bahsettikten sonra artık data işlemlerinde düzgün OOP ve alt yapının öneminden bahsetmeye başlayabiliriz.
Daha önceki makalelerimizdede bahsettiğim gibi artık bir çok projede kullanabileceğimiz kodlarımızı birer class dosyası halinde değil hem modülerlik hemde kalıtım ve daha az kod zaman için çıktısı dll olan ClassLibrary(Sınıf Kütüphanesi) halinde yazmamız gerektiğini söylemiştim.
Öncelikle OOP kullanırken üşengeçlüğümizden dolayo yaptığımız bir hatayı görelim.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
class code
{
public static SqlConnection bagla()
{
SqlConnection baglanti = new SqlConnection("Data Source=.;Uid=sa;pwd=12;Initial Catalog=AspNetDesign");
baglanti.Open();
return baglanti;
}
public static SqlCommand komut(string sorgu)
{
SqlCommand cmd = new SqlCommand(sorgu,code.bagla());
return cmd;
}
}
}
Şöyle bir sınıfımız var bu sınıfımızın adı kodlarındanda anlaşılabileceği gibi Code, bu sınıfımız aracılığı ile belleğimizde program kapanana kadar tutulan yani static methodlar tanımlamışız bunların isimleri bagla,komut methodlarımızı biraz incelersek bagla methodumuz ile baglantı açıyoruz ve komut methodumuzdada bu baglantı yoluyla her defasında baglantı cümlesini yazmak zorunda kalmadan SQL’den verilerimizi SqlCommand’ın ExecuteReader methoduyla elde edebiliyoruz. Örnek kodlarımıza ve buradaki yanlış kullanım sayesinde oluşan zaman uzuması sendromuna bir bakalım.
Stopwatch s = new Stopwatch();
s.Start();
SqlCommand cmd = code.komut("select * from tblCategory");
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Console.WriteLine(dr[0].ToString() +"---"+dr[1].ToString());
}
Bu kodlarımızın çıktısı şu şekilde oluyor
1---Aspx
2---C#
3---SQL
4---Linux
5---Java
6---Paketler
124,2909
Yani OOP kullandık,ileride başka bir projede kullanabileceğimiz bir class yazdık ve bunu 20-25 satırlık bir kod ile hallettik peki Code sınıfından her method içerisinde ayrı ayrı kurmamak için methodlarımızı static yaptık yani tembellik yaptık , Peki methodlarımız static olmasaydı ?
Kodlarımızı aşağıdaki gibi düzenlediğimizde
Code sınıfımız:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
class code
{
public SqlConnection bagla()
{
SqlConnection baglanti = new SqlConnection("Data Source=.;Uid=sa;pwd=12;Initial Catalog=AspNetDesign");
baglanti.Open();
return baglanti;
}
public SqlCommand komut(string sorgu)
{
SqlCommand cmd = new SqlCommand(sorgu,this.bagla());
return cmd;
}
}
}
Program.cs içerisindeki main methodu
Stopwatch s = new Stopwatch();
s.Start();
code c = new code();
SqlCommand cmd = c.komut("select * from tblCategory");
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Console.WriteLine(dr[0].ToString() + "---" + dr[1].ToString());
}
Ekranda şöyle bir çıktı oluşuyor
1---Aspx
2---C#
3---SQL
4---Linux
5---Java
6---Paketler
109,7957
Tam olarak 14,4952 milisaniye performans düştü.
Bir diğer yöntem ise alt yapı yazarak data işlemleri gerçekleştirmek bu gün çok büyük dataların döndüğü yerlerde Entity kullanılıyor ve entity de bu şekilde dinamik olarak sorgular geliştirilen bir dil.
Yukarıdaki kodlarımıza bakarsak aslında sadece kullanacağımız kolonların isimlerini çekmek çok mantıklı görünüyor.
Stopwatch s = new Stopwatch();
s.Start();
code c = new code();
SqlCommand cmd = c.komut("select CatName from tblCategory");
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Console.WriteLine(dr[0].ToString());
}
Yani şu şekilde ID kolonuna ihtiyacımız yoksa verileri böyle çekmek performansda değişikliklere sebep oluyor evet
Aspx
C#
SQL
Linux
Java
Paketler
76,9611
Çünkü belleğe almak için ayırılan bölge(stack) sadece CatName kolonundaki veriler ile dolduruluyor. Peki Sqlden bir kolon daha çekmek istediğimizde ne yapacağız ?
Kodlarımıza tekrar dönüp sql sorgumuzda değişiklik yapıp daha sonra bu değişikliklerin nedeni olan kolonunda kodlarını ekleyeceğiz peki sorgumuzda hiç değişiklik yapmasakda sadece kodlarımızda değişiklik yapsak ve buda çok performanslı olsa? Ne kadar güzel olur değil mi ?
Kategoriler isimli bir class dosyası oluşturuyoruz ve kodları şu şekilde
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Kategoriler
{
private int ID;
public int Numara
{
get { return ID; }
set { ID = value; }
}
private string NAME;
public string Isim
{
get { return NAME; }
set { NAME = value; }
}
public Kategoriler(int num,string nm)
{
this.ID = num;
this.Isim = nm;
}
}
}
Ve program.cs kodlarımızda şu şekilde
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Stopwatch s = new Stopwatch();
s.Start();
code c = new code();
SqlCommand cmd = c.komut("select * from TblCategory");
SqlDataReader dr = cmd.ExecuteReader();
List
h = new List();
while (dr.Read())
{
Kategoriler ha = new Kategoriler((int)dr["CatId"], (string)dr["CatName"]);
h.Add(ha);
}
foreach (var item in h)
{
Console.WriteLine("----" + item.Isim);
}
Console.WriteLine("\n" + s.Elapsed.TotalMilliseconds.ToString());
Console.ReadKey();
}
}
}
1----Aspx
2----C#
3----SQL
4----Linux
5----Java
6----Paketler
75,8604
Bütün kolonları seçtirdiğimiz halde programımız diğer kodlarımıza göre daha performanslı çalışıyor.
Alt yapının önemi performans ve kod aşamasında bu örneğimizde çektiğimiz 6 satır veri ile pek önemli görünmesede
40482 satırlık bir tabloda test sonuçları şu şekilde:
7022,6475 milisaniye alt yapı kullanıldı
11635,9274 milisaniye alt yapı kullanılmadı
Daha devasa verilerle çalıştığımızı düşünürsek performansın, yazdıgımız kod süresini , bakımını (bakım bir programın en pahalı bölgesidir), ve modülerliğini göz önüne alırsak alt yapı yazmak önemli.Umarım yararlı olmuştur
Keremalizm