lunedì 2 maggio 2011

DataTable.Select Vs DataTable.AsEnumerable()

Di recente mi sono posto l'allegra domanda di chi è più performante... Lo so che difficilmente quando Ms realizza qualcosa di nuovo lo passa come peggiore delle precedenti versioni, ma nel
passato qualche pecca l'aveva commessa ( anche se dobbiamo tornare all' RDO ?? ).

In questa prova mi sono messo di buzzo buono per comprendere che cosa combina "Lambda"
quando eseguiamo una selezione.

public class TestDataTableSelect
{
DataTable dt = new DataTable();

public TestDataTableSelect()
{

dt.Columns.Add("field1",typeof(int));
dt.Columns.Add("field2",typeof(string));


for (int i = 0; i < 1000000; i++)
{
dt.Rows.Add(new object[] { i, "A" + i.ToString() });
}
}

public void TestLambda(int selectorLimit)
{


DateTime ttStart = DateTime.Now;
Console.WriteLine(ttStart.ToShortTimeString() + "." +
ttStart.Second.ToString().PadLeft(2, '0') + "." +
ttStart.Millisecond.ToString().PadLeft(3, '0'));

var dr = dt.AsEnumerable().Where(r => (int)r["field1"] < selectorLimit);
DateTime ttEnd = DateTime.Now;

Console.WriteLine("Lambda:" + dr.Count());
Console.WriteLine(ttEnd.ToShortTimeString() + "." +
ttEnd.Second.ToString().PadLeft(2, '0') + "." +
ttEnd.Millisecond.ToString().PadLeft(3, '0'));

TimeSpan ts = ttEnd - ttStart;
Console.WriteLine("Totals:" +
ts.TotalMilliseconds.ToString().PadLeft(3, '0'));
}


public void TestFilter(int selectorLimit)
{

DateTime ttStart = DateTime.Now;
Console.WriteLine(ttStart.ToShortTimeString() + "." +
ttStart.Second.ToString().PadLeft(2, '0') + "." +
ttStart.Millisecond.ToString().PadLeft(3, '0'));

var dr = dt.Select("field1 < "+selectorLimit);
DateTime ttEnd = DateTime.Now;

Console.WriteLine("Normal:"+ dr.Count());
Console.WriteLine(ttEnd.ToShortTimeString() + "." +
ttEnd.Second.ToString().PadLeft(2, '0') + "." +
ttEnd.Millisecond.ToString().PadLeft(3, '0'));

TimeSpan ts = ttEnd - ttStart;
Console.WriteLine("Totals:" +
ts.TotalMilliseconds.ToString().PadLeft(3, '0'));
}
}

Con "stupore" ho notato che in debug, nell'atto della richiesta viene eseguita la
lambda e questo "tacitamente" implica che non solo è più veloce di
Select(string filter) ma i dati dovrebbero essere più vicini all'ultimo aggiornamento.

Questi i dati ottenuti ...

[ora inizio] Prototipo [numero elementi estrtti
[ora fine]
[millisecondi totali]

--------------------------------
09:04.44.034 Lambda:10
09:04.44.047
Totals:13,0008
--------------------------------
09:04.44.299 Normal:10
09:04.46.117
Totals:1818,104
--------------------------------
09:04.46.118 Lambda:100
09:04.46.118
Totals:000
--------------------------------
09:04.46.354 Normal:100
09:04.48.198
Totals:1844,1055
--------------------------------
09:04.48.198 Lambda:1000
09:04.48.198
Totals:000
--------------------------------
09:04.48.436 Normal:1000
09:04.50.273
Totals:1836,105
--------------------------------
09:04.50.276 Lambda:10000
09:04.50.276
Totals:000
--------------------------------
09:04.50.515 Normal:10000
09:04.52.375
Totals:1860,1064
--------------------------------
09:04.52.378 Lambda:100000
09:04.52.379
Totals:001
--------------------------------
09:04.52.627 Normal:100000
09:04.54.454
Totals:1827,1045
--------------------------------

Quanto meno sono omogenei.

Nessun commento: