使用c#dotnetzip.NET 4.0缓慢解压缩文本文件

使用c#dotnetzip.NET 4.0缓慢解压缩文本文件,c#,unzip,C#,Unzip,我正在制作一种从压缩文件中提取信息的方法。所有zip文件将只包含一个文本文件。方法应该返回一个字符串数组 我正在使用dotnetzip,但我正在体验一种令人不快的性能。我试图对每个步骤的性能进行基准测试,但似乎在所有步骤上都表现得很慢 c#代码是: 例如,我得到以下输出: 正在阅读xxxx.zip。。。ZipFile(0毫秒) 内存流(0ms) 提取物(234ms) 读取(78毫秒) 分割线(187ms) 完成(514ms) 在python 2.6中使用以下代码执行相同操作时,总共514毫秒:

我正在制作一种从压缩文件中提取信息的方法。所有zip文件将只包含一个文本文件。方法应该返回一个字符串数组

我正在使用dotnetzip,但我正在体验一种令人不快的性能。我试图对每个步骤的性能进行基准测试,但似乎在所有步骤上都表现得很慢

c#代码是:

例如,我得到以下输出:

正在阅读xxxx.zip。。。ZipFile(0毫秒) 内存流(0ms) 提取物(234ms) 读取(78毫秒) 分割线(187ms) 完成(514ms)

在python 2.6中使用以下代码执行相同操作时,总共514毫秒:

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

它只需89毫秒就可以执行。任何关于如何提高性能的想法都是非常受欢迎的。

您的代码不是以此类推的,因此这种比较是不公平的。一些要点:

  • 您是否尝试删除日志代码?
    AppendText
    调用将负责一些额外的时间
  • 在调用split之前,需要进行文件范围的替换,这将大大降低该过程的速度。只需在
    \r\n
    上拆分即可
  • 您可以将每一行转换为字符数组,而不仅仅是返回字符串。这也会减慢速度
  • 您可能希望比较不同的Zip库,看看是否有更快的提取方法
  • 重复调用
    StreamReader.ReadLine可能比读取整个流然后手动拆分要快

简言之,您应该分析一些替代方法,如果您想要真正的相似比较,您应该在不使用RichTextBox进行中间日志记录的情况下对代码计时。

谢谢您的建议。我最终通过以下几种方式更改了代码:

  • 使用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);
public List LoadZipFile2(字符串文件名)
{
列表行=新列表();
int start=System.Environment.TickCount;
字符串调试文本;
debugtext=“正在读取”+文件名+“…”;
this.richTextBoxLOG.AppendText(debugtext);
尝试
{
//int nstart=System.Environment.TickCount;
ZipFile zip=ZipFile.Read(文件名);
//这个.richTextBoxLOG.AppendText(String.Format(“ZipFile({0}ms)\n”,System.Environment.TickCount-nstart));
//nstart=System.Environment.TickCount;
MemoryStream ms=新的MemoryStream();
//这个.richTextBoxLOG.AppendText(String.Format(“Memorystream({0}ms)\n”,System.Environment.TickCount-nstart));
//nstart=System.Environment.TickCount;
zip[0]。提取(毫秒);
zip.Dispose();
//this.richTextBoxLOG.AppendText(String.Format(“Extract({0}ms)\n”,System.Environment.TickCount-nstart));
//nstart=System.Environment.TickCount;
使用(var读取器=新的StreamReader(ms))
{
reader.BaseStream.Seek(0,SeekOrigin.Begin);
while(reader.Peek()>=0)
{
添加(reader.ReadLine());
}
}
;
//这个.richTextBoxLOG.AppendText(String.Format(“Read({0}ms)\n”,System.Environment.TickCount-nstart));
}
捕获(IOEX异常)
{
this.richTextBoxLOG.AppendText(例如Message+“\n”);
}
int slut=System.Environment.TickCount;
这个.richTextBoxLOG.AppendText(String.Format(“Done({0}ms)\n”,slut-start));
返回(行);

我想您应该使用ICSharpCode.SharpZipLib Library与python代码不同,.NET代码更新UI,并在内存流中提供异常处理和缓冲区,因此这不是一个公平的比较。顺便说一句:nstart在记录拆分行后没有更新,所以完成=拆分行+删除建议。我在几种方法:-使用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);