Slow ZipFile.Save(Stream)

May 18, 2010 at 5:48 PM


I developed a web application which zips files using DotNetZip. Everything works as expected on my local dev machine and performance is good. When I deploy to a test environment however, performance seems to be pretty bad. I have nailed down the line that takes some time.

It's where I try to save the zipfile to a memorystream


This sometimes takes 90 (wow) seconds, sometimes 2 seconds and sometimes 15 seconds. It's very random, even with the same set of files that are being zipped I am only zipping 2 relatively small files (~1mb each); a pdf file and a doc file.

I was wondering if my test environment is simply unstable, or whether you could think of anything that could cause this behaviour? It's literally just the call to zipFile.Save(ms) that is slow.







May 18, 2010 at 7:59 PM

I have no good ideas. MemoryStream is an auto-expanding stream, so it may be having some problems re-allocating buffers as it expands.

Maybe you could describe more your design and why you're putting things into a memory stream.  How large is the zip file anyway?

Generally you don't want to retain the zip file in a memory stream.  You want to write it to the disk, or send it in the response stream.  Putting it all in the memory stream would be sort of unusual.

It could be that if you are sending the zip as a response, eliminating the memory stream would increase performance significantly.

May 18, 2010 at 8:38 PM

Thanks for replying Cheeso.

I am calling another API (which I don't own) which ultimately stores the zip file in a database (which I am not allowed to touch directly). This API call requires me to pass in a byte array. I am writing to the MemoryStream so I can easily get the bytes from it so I can pass them to the API call.

I am just a bit confused around the fact that it only behaves this poorly on my test environment, and the numbers seems to random (90 secs, 2 secs, 15 secs, etc) even tough I am zipping the same files. I will do some more investigation work tomorrow.

May 19, 2010 at 1:32 AM

ok well if you need the byte array then saving to a memory stream is probably the right thing.
There's one semi-exotic thing that happens during a save. If the thing to be saved is above a certain threshold, then DotNetZip will create multiple threads to do the compression.  See the documentation for the ParallelDeflateThreshold property

If your ASPNET system is thread-constrained, that may cause a surprising latency during the save.  To check if threading is the problem you can set ParallelDeflateThreshold to -1, which tells DotNetZip to never use separate threads.  If you see the same odd variation in performance, then ... it's not the threading.


May 19, 2010 at 9:15 AM

Awesome, that fixed it!

Every call to zipFile.Save(ms) is now consistently around 0.5 secs, which I am extremely happy with.

Thanks - you're the man! :)