| using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
namespace DataTableSelect
{
static class DataTableExtensions
{
public static DataTable ToDataTable<T>(this IList<T> data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach ( PropertyDescriptor prop in properties )
{
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
foreach ( T item in data )
{
DataRow row = table.NewRow();
foreach ( PropertyDescriptor prop in properties )
{
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
return table;
}
}
public class MyData
{
public int Code { get; set; }
public string Period { get; set; }
public int TypeCode { get; set; }
public int DetailID { get; set; }
public override string ToString()
{
return string.Format("Code: {0}; Period: {1}; TypeCode: {2}; DetailID: {3};", Code, Period, TypeCode, DetailID);
}
}
class Program
{
static void Main()
{
Console.WindowWidth = 120;
int count = 1 * 1000;
List<MyData> myList = CreateTestList();
DataTable table = myList.ToDataTable();
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
count = 2 * 1000;
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
count = 4 * 1000;
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
count = 8 * 1000;
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
count = 16 * 1000;
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
count = 100 * 1000;
GetResultsForList(count, myList);
GetResultsForTableWithLINQ(count, table);
GetResultsForTableWithSelect(count, table);
Console.WriteLine("Done...");
Console.ReadLine();
}
private static void GetResultsForList(int count, List<MyData> myList)
{
Measure("List",
() =>
{
for ( int i = 0; i < count; i++ )
{
foreach ( var myData in myList )
{
if ( myData.Period == "01.01.2016" && myData.DetailID == 10 )
{
break;
}
}
}
return count;
});
}
private static void GetResultsForTableWithLINQ(int count, DataTable table)
{
Measure("Table LINQ",
() =>
{
for ( int i = 0; i < count; i++ )
{
var q = table.AsEnumerable().Where(row => row.Field<string>("Period") == "01.01.2016" && row.Field<int>("DetailID") == 10);
var found = q.ToList().Count != 0;
}
return count;
});
}
private static void GetResultsForTableWithSelect(int count, DataTable table)
{
string filter2 = "Period='01.01.2016' AND DetailID=10";
Measure("Table Select",
() =>
{
for ( int i = 0; i < count; i++ )
{
var found = table.Select(filter2).Length != 0;
}
return count;
});
Console.WriteLine("=========================================================================");
}
private static List<MyData> CreateTestList()
{
List<MyData> foos = new List<MyData>();
for ( int i = 0; i < 20; i++ )
{
foos.Add(new MyData
{
Code = i,
TypeCode = i,
Period = i == 10 ? "01.01.2016" : string.Empty,
DetailID = i == 10 ? 10 : 0
});
}
return foos;
}
static void Measure(string name, Func<long> callback)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var mem = GC.GetTotalMemory(true);
var gc00 = GC.CollectionCount(0);
var gc01 = GC.CollectionCount(1);
var gc02 = GC.CollectionCount(2);
var sw = Stopwatch.StartNew();
var result = callback();
sw.Stop();
var mem2 = GC.GetTotalMemory(false);
var gc10 = GC.CollectionCount(0);
var gc11 = GC.CollectionCount(1);
var gc12 = GC.CollectionCount(2);
var memDelta = (mem2 - mem) / 1024.0;
var gcDelta0 = gc10 - gc00;
var gcDelta1 = gc11 - gc01;
var gcDelta2 = gc12 - gc02;
Console.WriteLine(
"{0,25}: {1,5}ms, ips: {2,22:N} | Mem: {3,6:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
name, sw.ElapsedMilliseconds, result / sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
}
}
}
|