public static byte[] Compress(byte[] data)
{
using (MemoryStream ms = new MemoryStream())
{
using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress))
{
ds.Write(data, 0, data.Length);
ds.Flush();
}
return ms.ToArray();
}
}
Will the memorystream be closed in the function above? Or is it better to assign the memorystream to an array and return the array instead?
public static byte[] Compress(byte[] data)
{
byte[] compressedData;
using (MemoryStream ms = new MemoryStream())
{
using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress))
{
ds.Write(data, 0, data.Length);
ds.Flush();
}
compressedData= ms.ToArray();
}
return compressedData;
}
Which of the codes better optimize memory usage?
Very similar results and not worth the effort.
To Answer your question the memory stream gets closed because it leaves scope and is in a using block meaning Dispose will get called ala the IDispose pattern. As an aside I personally prefer your second example as its easier to stop it in the debugger to check the contents of compressedData
. But this really isn't worth the effort to refactor in the name of performance.
There are bigger gains to be had elsewhere.
Example code here from MemoryStream.toArray
looks like this
byte[] numArray = new byte[this._length - this._origin];
Buffer.InternalBlockCopy(this._buffer, this._origin, numArray, 0, this._length - this._origin);
return numArray;
the reason the stream will be closed is because it is not held onto by your code at all and all references are dropped as the contents of the stream was copied to an array.
Inside memory stream is this code
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
this._isOpen = false;
this._writable = false;
this._expandable = false;
}
}
finally
{
base.Dispose(disposing); // ultimately this will dispose of the stream
}
}
I think you may be on the road to over-optimization, but alas...
Look at the IL code. More than likely, it ends up being the same code or very similar. This is a micro-optimization at it's finest.
Personally, I would go with option 1 for readability and less code.
The MemoryStream
will be closed in both cases. Thus, the code works identical, so the first version is better (since it's shorter and more clear). Memory usage is also identical, except additional additional reference variable compressedData
in second case, which will be destroyed after method exit.
Since no one has mentioned it, I would also add that MemoryStream does not need to be disposed. It may make some feel wrong not to close a stream, but you can rest assured, it absolutely does nothing to Dispose it, there are no resources to release, and so forth.
And of course, there is nothing to Flush either, as Flush is about writing to an internal array before writing to underlying stream ... MS has nowhere else to write but to inner buffer 'stream', so it is always flushed.
References like Albahari (C# x.x in a Nutshell) also repeat that MemoryStreams do not need disposed.