2012-07-03 37 views
5

Mã sau mất khoảng 2500 mili giây trên i7- * 3,4 GHz windows-7 máy tính 64 bit để đọc một bảng excel với 25000 dòng và 5 cột. Mỗi ô khoảng bao gồm một chuỗi có 10 ký tự. Nó có bình thường không? Làm thế nào tôi có thể đọc nó nhanh hơn?Hiệu suất của OLEDB để đọc Excel

Stopwatch sw1 = Stopwatch.StartNew(); 
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " + 
              "Extended Properties=Excel 12.0;", filename); 

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); 
+2

tập dữ liệu là các đối tượng "nặng", tạo tốt hơn lớp của riêng bạn và điền vào danh sách bằng cách sử dụng bộ dữ liệu – Boomer

+1

Tôi nghĩ rằng hầu hết chi phí hiệu suất là thời gian kết nối (hãy thử sửa đổi kích thước bản ghi để xem thời gian trôi qua tăng đáng kể) – Pynner

+0

Hãy thử để di chuyển khởi động của StopWatch sang sau khi kết nối đã được thực hiện và xem cách nhiều thời gian mà một phần mất. Nhưng như Boomer đã chỉ ra, hãy thử sử dụng OleDbCommand và OleDbDataReader thay vì OleDbDataAdapter và một DataSet và bạn cũng có thể đạt được một số tốc độ. –

Trả lời

6

Tôi muốn trình bày kết quả của mình như một câu trả lời vì hành vi luôn nhất quán.

Tôi đã sao chép mã của bạn và đặt bên trong sự kiện nhấp nút, chỉ cần thay đổi một chút để đảm bảo vứt bỏ bộ điều hợp và kết nối cho mọi thử nghiệm được thực hiện.

// 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); 
     } 
    } 

Vì vậy, về cơ bản, đây là mã của bạn. Mã này thực hiện trong 500ms. NHƯNG .... nếu tôi giữ tệp test.xls mở trong Excel 2010, thời gian thực thi sẽ nhảy lên 8000ms.

Tôi cũng đã cố gắng thay đổi mã này, nhưng kết quả cuối cùng đều giống nhau

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); 
      } 
     } 
    } 

và, không, nó không phải là Open() của OleDbConnection, luôn luôn là adapter.Fill()

+0

Tôi chưa bao giờ nghĩ lý do là tệp đang được mở. Cảm ơn bạn đã trả lời. – hrzafer

+0

Tôi nhận thấy hành vi tương tự với một dự án tôi đã làm việc trên đó đọc một lượng lớn dữ liệu từ Excel. Tôi đã không làm loại nghiên cứu để thu hẹp nguyên nhân, bởi vì dự án không thực sự yêu cầu bất kỳ loại hiệu suất nào (đó là một công cụ nội bộ vẫn kết thúc quá trình xử lý trong chưa đầy một phút). Tôi nhận thấy chắc chắn rằng nếu tôi mở bảng tính, có vẻ mất tới một phút để hoàn thành nơi có thể mất 10 giây với bảng tính không mở. Tôi nghĩ nó thật kỳ lạ, nhưng loại bài viết này xác nhận tôi không điên. – Jim

Các vấn đề liên quan