2012-08-03 109 views
0

我正在製作一種從壓縮文件中提取信息的方法。所有的zip文件將只包含一個文本文件。這意味着方法應該返回一個字符串數組。使用c#慢速解壓縮文本文件dotnetzip .NET 4.0

我正在使用dotnetzip,但我正在經歷一個可觀的表現。我試圖對每一步的表現進行基準測試,並且似乎在所有步驟上都表現得很慢。

C#代碼爲:

 public string[] LoadZipFile(string FileName) 
    { 
     string[] lines = { }; 
     int start = System.Environment.TickCount; 
     this.richTextBoxLOG.AppendText("Reading " + FileName + "... "); 
     try 
     { 
      int nstart; 

      nstart = System.Environment.TickCount;  
      ZipFile zip = ZipFile.Read(FileName); 
      this.richTextBoxLOG.AppendText(String.Format("ZipFile ({0}ms)\n", System.Environment.TickCount - nstart)); 

      nstart = System.Environment.TickCount; 
      MemoryStream ms = new MemoryStream(); 
      this.richTextBoxLOG.AppendText(String.Format("Memorystream ({0}ms)\n", System.Environment.TickCount - nstart)); 

      nstart = System.Environment.TickCount; 
      zip[0].Extract(ms); 
      this.richTextBoxLOG.AppendText(String.Format("Extract ({0}ms)\n", System.Environment.TickCount - nstart)); 

      nstart = System.Environment.TickCount; 
      string filecontents = string.Empty; 
      using (var reader = new StreamReader(ms)) 
      { 
       reader.BaseStream.Seek(0, SeekOrigin.Begin); 
       filecontents = reader.ReadToEnd().ToString(); 
      } 
      this.richTextBoxLOG.AppendText(String.Format("Read ({0}ms)\n", System.Environment.TickCount - nstart)); 

      nstart = System.Environment.TickCount; 
      lines = filecontents.Replace("\r\n", "\n").Split("\n".ToCharArray()); 
      this.richTextBoxLOG.AppendText(String.Format("SplitLines ({0}ms)\n", System.Environment.TickCount - nstart)); 
     } 
     catch (IOException ex) 
     { 
      this.richTextBoxLOG.AppendText(ex.Message+ "\n"); 

     } 
     int slut = System.Environment.TickCount; 
     this.richTextBoxLOG.AppendText(String.Format("Done ({0}ms)\n", slut - start)); 
     return (lines); 

例如,我得到這個輸出:

閱讀xxxx.zip ...的ZipFile(0毫秒) 的MemoryStream(0毫秒) 提取物(234ms) 閱讀(78ms) SplitLines(187ms) 完成(514ms)

總共514毫秒。當使用此代碼在python 2.6中執行相同的操作時:

def ReadZip(File): 
z = zipfile.ZipFile(File, "r") 
name =z.namelist()[0] 
return(z.read(name).split('\r\n')) 

它僅在89 ms內執行。任何關於如何提高性能的想法都非常受歡迎。

+0

我猜你應該使用ICSharpCode.SharpZipLib圖書館 – 2012-08-03 11:22:20

+0

不像Python代碼的.NET代碼更新了UI和功能異常處理和緩存在內存流,所以這不是一個公平的比較。順便說一句:在記錄SplitLines之後nstart沒有更新,所以Done = SplitLines + Done – mtijn 2012-08-03 11:27:47

回答

1

你的代碼並不像是一樣,所以比較是不公平的。一些重要的觀點:

  • 您是否試過刪除您的日誌代碼?撥打AppendText電話將負責一些額外的時間。
  • 在調用split之前,您需要進行文件級替換,這會大大減慢進程的這一部分。相反,只需拆分\r\n即可。
  • 您將每行轉換爲char數組而不僅僅是返回字符串。這也會減慢速度。
  • 您可能想要比較不同的Zip庫以查看是否有更快的提取方式。
  • 重複調用StreamReader.ReadLine可能會比讀取整個流然後手動分割更快。

簡而言之,您應該剖析一些替代方法,並且如果您希望進行類似於類似的比較,則應該在不使用RichTextBox進行中間日誌記錄的情況下計時。

+0

感謝您的建議。我使用幾種方法改變代碼: - 使用collection.generic返回行 - 使用streamreader.readline 刪除日誌記錄和異常處理不會改變性能。我看着sharplibs解壓縮庫,但它看起來實施起來稍微複雜一點,從其他文章中可以看出,解壓縮可能有一點點收穫。 它現在運行在300毫秒左右。 – user1573820 2012-08-10 06:45:44

1

感謝您的建議。我enden了在幾個方面改變代碼:

  • 使用collection.generic使用streamreader.readline

刪除日誌記錄和異常處理並沒有太大變化的性能返回線

  • 。我看着sharplibs解壓縮庫,但實現起來看起來更加複雜一些,從我在其他文章中可以看到的解壓縮可能有一點點收穫。它現在運行在300毫秒左右。

     public List<string> LoadZipFile2(string FileName) 
        { 
         List<string> lines = new List<string>(); 
         int start = System.Environment.TickCount; 
         string debugtext; 
         debugtext = "Reading " + FileName + "... "; 
         this.richTextBoxLOG.AppendText(debugtext); 
    
         try 
         { 
          //int nstart = System.Environment.TickCount; 
          ZipFile zip = ZipFile.Read(FileName); 
          // this.richTextBoxLOG.AppendText(String.Format("ZipFile ({0}ms)\n", System.Environment.TickCount - nstart)); 
    
          //nstart = System.Environment.TickCount; 
          MemoryStream ms = new MemoryStream(); 
          //this.richTextBoxLOG.AppendText(String.Format("Memorystream ({0}ms)\n", System.Environment.TickCount - nstart)); 
    
          //nstart = System.Environment.TickCount; 
          zip[0].Extract(ms); 
          zip.Dispose(); 
          //this.richTextBoxLOG.AppendText(String.Format("Extract ({0}ms)\n", System.Environment.TickCount - nstart)); 
    
          //nstart = System.Environment.TickCount; 
          using (var reader = new StreamReader(ms)) 
          { 
           reader.BaseStream.Seek(0, SeekOrigin.Begin); 
           while (reader.Peek() >= 0) 
           { 
            lines.Add(reader.ReadLine()); 
           } 
          } 
          ; 
          //this.richTextBoxLOG.AppendText(String.Format("Read ({0}ms)\n", System.Environment.TickCount - nstart)); 
         } 
         catch (IOException ex) 
         { 
          this.richTextBoxLOG.AppendText(ex.Message + "\n"); 
         } 
         int slut = System.Environment.TickCount; 
         this.richTextBoxLOG.AppendText(String.Format("Done ({0}ms)\n", slut - start)); 
         return (lines);