He estado experimentando con formas de leer datos de un servidor SQL lo más rápido posible y encontré un descubrimiento interesante. Si leo los datos en un List<object[]>
en lugar de un List<string[]>
, el rendimiento aumenta en más del doble.SqlDataReader Lista de rendimiento <string[]> o Lista <object[]>
Sospecho que esto se debe a no tener que llamar al método ToString()
en los campos, pero siempre pensé que el uso de objetos tenía un impacto negativo en el rendimiento.
¿Hay alguna razón para no usar una lista de matrices de objetos en lugar de matrices de cadenas?
EDIT: una idea que tuve fue el tamaño de almacenamiento de esta información. ¿Almacenar los datos en matrices de objetos requiere más espacio que cadenas?
Aquí está mi código de prueba:
private void executeSqlObject()
{
List<object[]> list = new List<object[]>();
using (SqlConnection cnn = new SqlConnection(_cnnString))
{
cnn.Open();
SqlCommand cmd = new SqlCommand("select * from test_table", cnn);
SqlDataReader reader = cmd.ExecuteReader();
int fieldCount = reader.FieldCount;
while (reader.Read())
{
object[] row = new object[fieldCount];
for (int i = 0; i < fieldCount; i++)
{
row[i] = reader[i];
}
list.Add(row);
}
}
}
private void executeSqlString()
{
List<string[]> list = new List<string[]>();
using (SqlConnection cnn = new SqlConnection(_cnnString))
{
cnn.Open();
SqlCommand cmd = new SqlCommand("select * from test_table", cnn);
SqlDataReader reader = cmd.ExecuteReader();
int fieldCount = reader.FieldCount;
while (reader.Read())
{
string[] row = new string[fieldCount];
for (int i = 0; i < fieldCount; i++)
{
row[i] = reader[i].ToString();
}
list.Add(row);
}
}
}
private void runTests()
{
Stopwatch watch = new Stopwatch();
for (int i = 0; i < 10; i++)
{
watch.Start();
executeSqlObject();
Debug.WriteLine("Object Time: " + watch.ElapsedMilliseconds.ToString());
watch.Reset();
}
for (int i = 0; i < 10; i++)
{
watch.Start();
executeSqlString();
Debug.WriteLine("String Time: " + watch.ElapsedMilliseconds.ToString());
watch.Reset();
}
}
Y los resultados:
Object Time: 879
Object Time: 812
Object Time: 825
Object Time: 882
Object Time: 880
Object Time: 905
Object Time: 815
Object Time: 799
Object Time: 823
Object Time: 817
Average: 844
String Time: 1819
String Time: 1790
String Time: 1787
String Time: 1856
String Time: 1795
String Time: 1731
String Time: 1792
String Time: 1799
String Time: 1762
String Time: 1869
Average: 1800
No se puede discutir con los resultados. También debe envolver a sus lectores (y también a los comandos) en las instrucciones de uso, ya que pueden perder memoria. –
Tiene que haber algún problema con la prueba ... En comparación con la lectura de los datos de la base de datos, hacer que el tipo de cadena revise * debe * ser insignificante. – Guffa
Por curiosidad, ¿es diferente si simplemente convierte el valor del lector en una cadena ('row [i] = (string) reader [i];') en lugar de llamar 'ToString()' en él, o en su lugar, utilizando el método 'SqlDataReader.GetString()' incorporado para recuperar el valor ('row [i] = reader.GetString (i);')? (Asumiendo que todos los valores de columna son cadenas.) –