When creating purposes you’ll usually must cope with strings. And since string objects are pricey by way of efficiency, you’ll usually need to compress your string content material, i.e., the information inside your string objects, to scale back the payload. There are a number of libraries accessible to do that however two in style strategies are GZip and Brotli.
On this article we’ll focus on how one can compress and decompress strings utilizing the GZip and Brotli algorithms in C#. To work with the code examples supplied right here, you must have Visible Studio 2022 put in in your system. If you happen to don’t have already got a duplicate, you’ll be able to download Visual Studio 2022 here.
Create a console software challenge in Visible Studio 2022
First off, let’s create a .NET Core console software challenge in Visible Studio. Assuming Visible Studio 2022 is put in in your system, comply with the steps outlined beneath to create a brand new .NET Core console software challenge.
- Launch the Visible Studio IDE.
- Click on on “Create a brand new challenge.”
- Within the “Create a brand new challenge” window, choose “Console App” from the record of templates displayed.
- Click on Subsequent.
- Within the “Configure your new challenge” window proven subsequent, specify the title and placement for the brand new challenge.
- Within the “Further Info” window, choose .NET 6.0 because the runtime and click on Subsequent.
- Click on Create.
We’ll use this challenge for instance string compression and decompression beneath. However first we’ll set up a benchmarking package deal, BenchmarkDotNet, which is able to enable us to measure the advantages we achieve from compression.
Set up the BenchmarkDotNet NuGet package deal
Benchmarking code is important to understanding the efficiency of your software. On this article we’ll reap the benefits of BenchmarkDotNet to trace the efficiency of the strategies. If you happen to’re not acquainted with BenchmarkDotNet, I counsel studying this article first.
To work with BenchmarkDotNet you will need to set up the BenchmarkDotNet package deal. You are able to do this by way of the NuGet Package deal Supervisor inside Visible Studio 2022, or by executing the next command on the NuGet Package deal Supervisor Console:
Set up-Package deal BenchmarkDotNet
The System.IO.Compression namespace in C#
The System.IO.Compression namespace includes strategies to compress recordsdata and strings. It accommodates two compression algorithms: GZip and Brotli. On this sections that comply with, we’ll study how we will compress and decompress string knowledge utilizing each GZip and Brotli compression algorithms in C#.
We’ll use the next textual content within the examples beneath:
string originalString = "To work with BenchmarkDotNet you will need to set up the BenchmarkDotNet package deal. " +
"You are able to do this both by way of the NuGet Package deal Supervisor contained in the Visible Studio 2019 IDE, " +
"or by executing the Set up-Package deal BenchmarkDotNet command on the NuGet Package deal Supervisor Console";
Compress and decompress knowledge utilizing GZip in C#
The next code snippet exhibits how one can compress knowledge utilizing the GZipStream class in C#. Observe that the parameter to the Compress methodology is a byte array.
public static byte[] Compress(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream())
{
utilizing (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimum))
{
gzipStream.Write(bytes, 0, bytes.Size);
}
return memoryStream.ToArray();
}
}
To decompress knowledge that has been compressed utilizing the GZip algorithm, we will use the next methodology.
public static byte[] Decompress(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream(bytes))
{
utilizing (var outputStream = new MemoryStream())
{
utilizing (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}
Working the GZip compression algorithm
You should use the next code snippet to execute the GZip compression strategies we simply created.
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = GZipCompressor.Compress(dataToCompress);
string compressedString = Encoding.UTF8.GetString(compressedData);
Console.WriteLine("Size of compressed string: " + compressedString.Size);
byte[] decompressedData = GZipCompressor.Decompress(compressedData);
string deCompressedString = Encoding.UTF8.GetString(decompressedData);
Console.WriteLine("Size of decompressed string: " + deCompressedString.Size);
While you run the above code, you’ll see the next output within the console window.
Determine 1. GZip compressed the unique string of 259 characters into 167 characters.
Observe that GZip trimmed 92 characters from the unique string of 259 characters. As a result of the unique string and the decompressed string needs to be similar, their lengths must also be the identical.
Compress and decompress knowledge utilizing Brotli in C#
The next code snippet illustrates how one can compress knowledge utilizing the BrotliStream class in C#. As within the GZip instance above, be aware that the parameter to the Compress methodology is a byte array.
public static byte[] Compress(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream())
{
utilizing (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimum))
{
brotliStream.Write(bytes, 0, bytes.Size);
}
return memoryStream.ToArray();
}
}
And right here is how you should use BrotliStream to decompress the information:
public static byte[] Decompress(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream(bytes))
{
utilizing (var outputStream = new MemoryStream())
{
utilizing (var decompressStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}
Working the Brotli compression algorithm
The next code snippet exhibits how one can compress a string utilizing the Brotli compression methodology we created above.
Console.WriteLine("Size of unique string: " + originalString.Size);
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = BrotliCompressor.Compress(dataToCompress);
string compressedString = Convert.ToBase64String(compressedData);
Console.WriteLine("Size of compressed string: " + compressedString.Size);
byte[] decompressedData = BrotliCompressor.Decompress(compressedData);
string deCompressedString = Convert.ToBase64String(decompressedData);
Console.WriteLine("Size of decompressed string: " + deCompressedString.Size);
While you run this system, you will notice the next output within the console window.
Determine 2. Brotli compressed the unique string of 259 characters into 121 characters.
As you’ll be able to see, Brotli does a significantly better job of compression than GZip. Nonetheless, the compression ratio isn’t the entire story, as we’ll see beneath.
Asynchronous compression and decompression with GZip and Brotli
Observe that there are asynchronous counterparts to the compression and decompression strategies we used earlier. Listed here are the asynchronous variations of the Compress and Decompress strategies utilizing the GZip algorithm:
public async static Process<byte[]> CompressAsync(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream())
{
utilizing (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimum))
{
await gzipStream.WriteAsync(bytes, 0, bytes.Size);
}
return memoryStream.ToArray();
}
}
public async static Process<byte[]> DecompressAsync(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream(bytes))
{
utilizing (var outputStream = new MemoryStream())
{
utilizing (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
await decompressStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}
And listed here are the asynchronous variations of the Compress and Decompress strategies utilizing Brotli:
public static async Process<byte[]> CompressAsync(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream())
{
utilizing (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimum))
{
await brotliStream.WriteAsync(bytes, 0, bytes.Size);
}
return memoryStream.ToArray();
}
}
public static async Process<byte[]> DecompressAsync(byte[] bytes)
{
utilizing (var memoryStream = new MemoryStream(bytes))
{
utilizing (var outputStream = new MemoryStream())
{
utilizing (var brotliStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
await brotliStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}
Benchmarking compression and decompression with GZip and Brotli in C#
Within the console software challenge we created earlier, create a brand new file named BenchmarkCompression.cs and enter the next code.
[MemoryDiagnoser]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class BenchmarkCompression
{
string originalString = "To work with BenchmarkDotNet you will need to set up the BenchmarkDotNet package deal. " +
"You are able to do this both by way of the NuGet Package deal Supervisor contained in the Visible Studio 2019 IDE, " +
"or by executing the Set up-Package deal BenchmarkDotNet command on the NuGet Package deal Supervisor Console";[Benchmark]
public void GZipCompress()
{
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
var compressedData = GZipCompressor.Compress(dataToCompress);
}[Benchmark]
public void BrotliCompress()
{
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
var compressedData = BrotliCompressor.Compress(dataToCompress);
}
}
While you run the benchmarks, you must see console output just like that proven in Determine 3 beneath.
Determine 3. The outcomes from BenchmarkDotNet… GZip wins!
Clearly, compression ratio isn’t the one consideration when selecting a compression algorithm. Though, in comparison with GZip, you’ll be able to obtain significantly better compression utilizing Brotli, the extra compression comes at the price of efficiency. GZip is considerably quicker than Brotli at compressing and decompressing knowledge.
When benchmarking your .NET software, you must all the time be certain that you run your challenge in launch mode. The reason being that the compiler optimizes the code in another way for debug and launch modes. I’ll have extra to say about benchmarking and software efficiency in future posts right here.
Copyright © 2022 IDG Communications, Inc.