Siempre he creído que DataTable consumiría más memoria que una lista genérica. Estoy probando cargar una DataTable y cargar una lista desde una consulta de SQL Server. En este caso, DataTable consume menos memoria. Obtengo las 2000 mejores filas y hay 134 campos por fila. Un campo binario y el resto son varchar estándar, int, bit y así sucesivamente.¿Lista <object[]> usando más memoria que DataTable?
¿Cómo podría una DataTable con todos sus gastos generales consumir menos memoria que List? El GC informa aproximadamente 4mb con DataTable y 5mb con list.
Hice la prueba con algunas de las tablas NorthWind y la lista fue marginalmente menor en esos casos.
private void GetMemory()
{
label1.Text = string.Format("{0:0.00} MB", GC.GetTotalMemory(true)/1024.0/1024.0);
}
private void DataTableButton_Click(object sender, EventArgs e)
{
var conn = new SqlConnection(@"Initial Catalog=ADatabase;Data Source=AServer;Integrated Security=True");
conn.Open();
var cmd = new SqlCommand("SELECT TOP 2000 * FROM AManyColumnedTable", conn);
var r = cmd.ExecuteReader();
_rows = new List<object[]>();
//uses more memory
object[] a = null;
while (r.Read())
{
a = new object[r.FieldCount];
r.GetValues(a);
_rows.Add(a);
}
//uses less memory
//_table = new DataTable("TheTable");
//_table.Load(r);
r.Close();
conn.Close();
GetMemory();
}
Interesante, intenté llamar a GC.Collect directamente después de cargar la Lista, desafortunadamente no cambió el resultado. Usé GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced) ;. Jugaré con los boxings. No pensé en eso, gracias. Intentaba mantenerlo genérico usando GetValues.Estoy viendo la implementación de DataRow y su uso de una clase DataStorage para contener valores, no un objeto [] como supuse que lo hizo. Nunca he oído hablar de la clase DataStorage, tal vez sería útil. ¡Gracias por la información! +1 – Steve
Tienes razón, fue el boxeo el que consumió la memoria extra. Acabo de intentar cargar los valores de la fila en listas genéricas y las listas hechas usan tipos de datos primitivos no nulables. La memoria era de 3.8mb. El DataTable fue de 4.4mb. ¡Buena llamada! – Steve