12 Ocak 2013 Cumartesi

Distinct : DataView.ToTable Vs Linq


Büyük veriler üzerinde işlem yaparken, kullandığımız yönteme çok dikkat etmeliyiz.

Projelerden birinde 350.000 satırlık veri kümesi üzerinde işlemler yapıp, düzenli bir veri modeline dönüştüreceğim. işlemler sırasında Distinct() işlemi uygulamam gerekmekteydi. 2 yöntem kullanarak işlemi gerçekleştirdim ve aralarındaki uçurum inanılmaz farklı çıktı.

Distinct -> DataView.ToTable Vs Linq

veri sayımız küçük olduğunda DataView.ToTable ile işlem yapmasında performanse çok sorun oluşturmuyor gibi. ama veri kümesi arttıkça inanılmaz bir yavaşlama söz konusu. bu yavaşlamayı en kolay linq ile kolaylıkla çözmekteyiz.

Performans test kodları ve sonuçları;


data.DefaultView.ToTable(true, "Id", "Name", "Role", "DC1", "DC2", "DC3", "DC4", "DC5", "DC6", "DC7");
VS
data.AsEnumerable().Distinct(System.Data.DataRowComparer.Default).ToList();

Veri kümemizi oluşturma işlemi;
private static DataTable GenerateTable(int noOfRows, int modules)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("Id", typeof(int));
    dt.Columns.Add("Name", typeof(string));
    dt.Columns.Add("Role", typeof(string));
    dt.Columns.Add("DC1", typeof(string));
    dt.Columns.Add("DC2", typeof(string));
    dt.Columns.Add("DC3", typeof(string));
    dt.Columns.Add("DC4", typeof(string));
    dt.Columns.Add("DC5", typeof(string));
    dt.Columns.Add("DC6", typeof(string));
    dt.Columns.Add("DC7", typeof(string));

    for (int i = 0; i < noOfRows; i++)
    {
        int id = i % modules;
        dt.Rows.Add(new object[] { id, "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString(), "Test" + id.ToString() });
    }
    return dt;
}

Performans hesaplama kısmı;
 
static void Main(string[] args)
{
    Display display = null;
    for (int i = 1; i < 1000; i += 100)
    {
        DataTable data = GenerateTable(1000 * i, 10 * i);

        display = new Display();

        sw.Start();
        DataTable distictData = data.DefaultView.ToTable(true, "Id", "Name", "Role", "DC1", "DC2", "DC3", "DC4", "DC5", "DC6", "DC7");
        display.ItemsInfo = data.Rows.Count + "/" + distictData.Rows.Count;
        display._ToTable = sw.ElapsedMilliseconds;
        sw.Stop();

        sw.Restart();
        var result = data.AsEnumerable().Distinct(System.Data.DataRowComparer.Default).ToList();
        display._Linq = sw.ElapsedMilliseconds;
        sw.Stop();

        list.Add(display);
    }

    writeConsole();

    Console.ReadKey();
}
 
private static void writeConsole()
{
    Console.WriteLine("ItemCount/DistinctItem  |  DataView ToTable   |   Linq");
    foreach (Display d in list)
    {
        Console.WriteLine(string.Format("         {0}            |         {1}         |   {2}", d.ItemsInfo, d._ToTable, d._Linq));
    }
}

Sonuçlar milliseconds olarak verilmektedir.

Bunun dışında Microsoft un yayınladığı bir makale daha var. Genel performans için dikkat edilmesi gerekenler.

Performance Tips and Tricks in .NET Applications -> http://msdn.microsoft.com/en-us/library/ms973839.aspx

1 yorum: