2012-07-03 18 views
5

Aşağıdaki kod, 25000 satır ve 5 sütun içeren bir excel sayfasını okumak için bir i7- * 3.4 GHz windows-7 64-bit bilgisayar üzerinde 2500 milisaniye sürer. Her bir hücre yaklaşık 10 karakterli bir dize içerir. Bu normal mi? Nasıl daha hızlı okuyabilirim?OLEDB'nin Excel'in okunması için performansı

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

veri kümesi, "ağır" nesnelerdir, daha iyi kendi sınıfınızı oluşturun ve datareader – Boomer

+1

kullanarak bir listesini doldurun. Performans maliyetinin çoğunun bağlantı süresi olduğunu düşünüyorum (geçen sürenin önemli ölçüde arttığını görmek için kayıt kümesi boyutunu değiştirmeyi deneyin) – Pynner

+0

Bağlantı yapıldıktan sonra StopWatch başlangıcına geçmek ve nasıl yapıldığını görmek için bu kadar zaman alır. Ancak Boomer'in işaret ettiği gibi, OleDbDataAdapter ve bir DataSet yerine OleDbCommand ve OleDbDataReader kullanmayı deneyin ve ayrıca biraz hız kazanabilirsiniz. –

cevap

6

Bulguları yanıt olarak sunmak isterim çünkü davranış her zaman tutarlı olur.

Kodunuzu kopyaladım ve bir düğme tıklatma olayının içine koydum, adaptörün ve yapılan tüm testlerin bağlantısını bertaraf ettiğinizden emin olmak için biraz değiştirdim.

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

Bu, temel olarak sizin kodunuz. Bu kod 500 ms'de yürütülür. ANCAK .... Eğer test.xls dosyasını Excel 2010'da açık tutarsam, yürütme süresi 8000 ms'ye atlar.

Ben de bu kod varyasyon denedi fakat sonuçlar aynı

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

ve hayır, o OleDbConnection Open() değil, her zaman adapter.Fill olduğunu

()

+0

Bunun nedeninin dosyanın açıldığını hiç düşünmemiştim. Cevap için teşekkür ederim. – hrzafer

+0

Çalıştığım bir projeyle, Excel'den büyük miktarda veri okuyan benzer davranışları fark ettim. Sebepleri daraltmak için bir tür araştırma yapmamıştım çünkü proje gerçekten herhangi bir performans gerektirmiyordu (bu, bir dakikadan daha kısa bir süre içinde işlenmeyi tamamlayan bir dahili araç). Tabii e-tablo açık olsaydı, elektronik tablo açılmamış olduğu 10 saniye sürebilirdi tamamlamak için bir dakika kadar sürdü gibi görünüyor eminim. Garip olduğunu düşündüm ama bu yazı bir türlü delirmediğimi doğruluyor. – Jim