Я хочу представить свои выводы в качестве ответа, потому что поведение всегда последовательное.
Я скопировал ваш код и помещал его в событие с нажатием кнопки, просто изменил бит, чтобы убедиться в том, что вы выбрали адаптер и соединение для каждого сделанного теста.
// 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);
}
}
Таким образом, это в основном ваш код. Этот код выполняется в 500 мс. BUT .... Если я сохраню файл test.xls открытым в Excel 2010, время выполнения перейдет в 8000мс.
Я также попробовал этот вариант кода, но конечный результат тот же
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);
}
}
}
и нет, это не Open() из OleDbConnection, всегда adapter.Fill()
dataset - это «тяжелые» объекты, лучше создать свой собственный класс и заполнить его список, используя datareader – Boomer
. Я думаю, что большая часть стоимости исполнения - это время соединения (попробуйте изменить размер набора записей, чтобы увидеть, если истекшее время резко возрастает) – Pynner
Попробуйте для перемещения начала StopWatch после того, как соединение было выполнено, и посмотреть, как много времени, которое занимает часть. Но, как уже указывал Бумер, попробуйте использовать OleDbCommand и OleDbDataReader вместо OleDbDataAdapter и DataSet, и вы также можете получить довольно высокую скорость. –