Deseo presentar mis hallazgos como respuesta porque el comportamiento siempre es coherente.
He copiado su código y lo he puesto dentro de un evento de clic de botón, solo lo he cambiado un poco para asegurarme de disponer el adaptador y la conexión para cada prueba realizada.
// test.xls contains 26664 rows by 5 columns. Average 10 char for column, file size is 2448kb
// OS Windows 7 Ultimate 64 bit. CPU Intel Core2 Quad Q9550 2.83ghz
// 8gb ram and disk C is an 256gb SSD cruzer
private void button1_Click(object sender, EventArgs e)
{
string filename = "c:\\tmp\\test.xls";
Stopwatch sw1 = Stopwatch.StartNew();
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " +
"Extended Properties=Excel 12.0", filename);
using(var adapter = new OleDbDataAdapter("SELECT * FROM [roots$]", connectionString))
{
var ds = new DataSet();
adapter.Fill(ds, "roots");
sw1.Stop();
Console.WriteLine("Time taken for excel roots: {0} ms", sw1.Elapsed.TotalMilliseconds);
}
}
Así que este es básicamente su código. Este código se ejecuta en 500ms. PERO .... si mantengo el archivo test.xls abierto en Excel 2010, el tiempo de ejecución salta a 8000ms.
también he tratado de esta variación de código, pero los resultados finales son los mismos
private void button1_Click(object sender, EventArgs e)
{
string filename = "c:\\tmp\\test.xls";
Stopwatch sw1 = Stopwatch.StartNew();
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " +
"Extended Properties=Excel 12.0", filename);
using(OleDbConnection cn = new OleDbConnection(connectionString))
{
cn.Open();
using(var adapter = new OleDbDataAdapter("SELECT * FROM [roots$]", cn))
{
var ds = new DataSet();
adapter.Fill(ds, "roots");
sw1.Stop();
Console.WriteLine("Time taken for excel roots: {0} ms", sw1.Elapsed.TotalMilliseconds);
}
}
}
y no, no es el Open() de la OleDbConnection, es siempre el adapter.Fill()
conjunto de datos son objetos "pesados", mejor crea tu propia clase y completa una lista usando Datareader – Boomer
Creo que la mayor parte del costo de rendimiento es el tiempo de conexión (intenta modificar el tamaño del conjunto de registros para ver si el tiempo transcurrido aumenta dramáticamente) – Pynner
Prueba para mover el inicio del cronómetro a después de haber hecho la conexión y ver cómo mucho tiempo que toma esa parte. Pero como Boomer ya señaló, intente utilizar OleDbCommand y OleDbDataReader en lugar de OleDbDataAdapter y un DataSet, y también podría ganar bastante velocidad. –