{
  "WorkItem": {
    "AffectedComponent": {
      "Name": "",
      "DisplayName": ""
    },
    "ClosedComment": "",
    "ClosedDate": null,
    "CommentCount": 0,
    "Custom": null,
    "Description": "It takes a very long time before the AddDirectory function returns when called on a large directory set. Directory that contains ~10GB in about 4000 sub-directories and 42000 files takes about 15 minutes to preprocess. That is before the Save method is called. I assume this might be down to 45000 calls to new ZipEntry? Would it be possible to calculate the overall number of ZipEntries necessary and create them as an array, rather than List instead? I tried to play with the source for AddOrUpdateDirectoryImpl and changed its body to be non-recursive, which improved the performance marginally (takes 14 minutes instead of 16 now) but still there has to be a way to speed things up.\n \nDotNetZip takes 40 minutes to zip the directory, where SharpZipLib only 25 (if AddDirectory becomes significantly faster, then the benchmarks might become similar)",
    "LastUpdatedDate": "2013-02-21T18:44:24.34-08:00",
    "PlannedForRelease": "",
    "ReleaseVisibleToPublic": false,
    "Priority": {
      "Name": "Low",
      "Severity": 50,
      "Id": 1
    },
    "ProjectName": "DotNetZip",
    "ReportedDate": "2009-04-01T09:21:41.71-07:00",
    "Status": {
      "Name": "Proposed",
      "Id": 1
    },
    "ReasonClosed": {
      "Name": "Unassigned"
    },
    "Summary": "AddDirectory takes ages for large archives",
    "Type": {
      "Name": "Issue",
      "Id": 3
    },
    "VoteCount": 5,
    "Id": 7406
  },
  "FileAttachments": [],
  "Comments": [
    {
      "Message": "I thought I might drop the mods that I made here in case you decide to incorporate them:\r\n<pre>\r\n        private ZipEntry AddOrUpdateDirectoryImpl(string directoryName, string rootDirectoryPathInArchive, AddOrUpdateAction action)\r\n        {\r\n            if (rootDirectoryPathInArchive == null)\r\n            {\r\n                rootDirectoryPathInArchive = \"\";\r\n                //System.IO.Path.GetDirectoryName(SharedUtilities.TrimVolumeAndSwapSlashes(directoryName));\r\n                //SharedUtilities.TrimVolumeAndSwapSlashes(directoryName);\r\n            }\r\n\r\n            //return AddOrUpdateDirectoryImpl(directoryName, rootDirectoryPathInArchive, action, 0);\r\n            return AddOrUpdateDirectoryImplTN(directoryName, rootDirectoryPathInArchive, action);\r\n        }\r\n\r\n        private ZipEntry AddOrUpdateDirectoryImplTN(string directoryName, string rootDirectoryPathInArchive, AddOrUpdateAction action)\r\n        {\r\n            //if (Verbose) StatusMessageTextWriter.WriteLine(\"{0} {1}...\",\r\n            //                   (action == AddOrUpdateAction.AddOnly) ? \"adding\" : \"Adding or updating\", directoryName);\r\n\r\n            string[] subdirs = System.IO.Directory.GetDirectories(directoryName, \"*\", System.IO.SearchOption.AllDirectories);\r\n            string dirForEntries;\r\n           \r\n            ZipEntry baseDir = ZipEntry.Create(directoryName, rootDirectoryPathInArchive);\r\n\r\n            baseDir.ProvisionalAlternateEncoding = this.ProvisionalAlternateEncoding;  // workitem 6410\r\n            baseDir._Source = EntrySource.Filesystem;\r\n            baseDir.MarkAsDirectory();\r\n            baseDir._zipfile = this;\r\n\r\n            // check for uniqueness:\r\n            ZipEntry e = this[baseDir.FileName];\r\n            if (e == null)\r\n            {\r\n                _entries.Add(baseDir);\r\n                _contentsChanged = true;\r\n            }\r\n\r\n            foreach(string folder in subdirs)\r\n            {\r\n                dirForEntries = folder.Substring(directoryName.Length + 1);\r\n                dirForEntries = System.IO.Path.Combine(rootDirectoryPathInArchive, dirForEntries);\r\n\r\n                ZipEntry dir = ZipEntry.Create(directoryName, dirForEntries);\r\n                //Console.Out.WriteLine(dirForEntries);\r\n                dir.ProvisionalAlternateEncoding = this.ProvisionalAlternateEncoding;  // workitem 6410\r\n                dir._Source = EntrySource.Filesystem;\r\n                dir.MarkAsDirectory();\r\n                dir._zipfile = this;\r\n\r\n                // check for uniqueness:\r\n                e = this[dir.FileName];\r\n                if (e == null)\r\n                {\r\n                    _entries.Add(dir);\r\n                    _contentsChanged = true;\r\n                }\r\n                String[] filenames = System.IO.Directory.GetFiles(folder);\r\n                // add the files: \r\n                foreach (String filename in filenames)\r\n                {\r\n                    if (action == AddOrUpdateAction.AddOnly)\r\n                        AddFile(filename, dirForEntries);\r\n                    else\r\n                        UpdateFile(filename, dirForEntries);\r\n                }\r\n            }\r\n\r\n            return baseDir;\r\n        }\r\n</pre>",
      "PostedDate": "2009-04-01T09:28:04.803-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-04-04T05:39:24.39-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Thanks for the work item, and the code.\r\n\r\nWhat version of the library are you using?  Recently there have been a couple of requests for better performance.  Looking into those requests, I realized that the I have been distributing a DEBUG version of the library.  Simply compiling the library in RELEASE configuration can improve performance 40% or more.   The most recent v1.8 release - the runtime, not the devkit - is available in RELEASE mode.  \r\n\r\nThis doesn't directly address your particular issue with the perf of AddOrUpdateDirectoryImpl, but it will help.   \r\n\r\nThere is also workitem 5183, http://dotnetzip.codeplex.com/WorkItem/View.aspx?WorkItemId=5183, which will help when it is addressed.  \r\n\r\nSeparately, I will have a look at your particular issue.\r\n",
      "PostedDate": "2009-04-15T12:37:57.2-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-05-27T06:02:53.433-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2010-08-11T10:37:39.697-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2011-09-27T07:39:05.093-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-02-21T18:44:24.34-08:00",
      "Id": -2147483648
    }
  ]
}