Uygulamalar geliştirirken genellikle dizelerle uğraşmanız gerekecektir. Ve dize nesneleri performans açısından maliyetli olduğundan, yükü azaltmak için genellikle dize içeriğinizi, yani dize nesnelerinizdeki verileri sıkıştırmak isteyeceksiniz. Bunu yapmak için kullanılabilecek birkaç kütüphane var, ancak iki popüler teknik GZip ve Brotli’dir.
Bu makalede, C#’ta GZip ve Brotli algoritmalarını kullanarak dizeleri nasıl sıkıştırabileceğinizi ve açabileceğinizi tartışacağız. Burada verilen kod örnekleriyle çalışmak için sisteminizde Visual Studio 2022 kurulu olmalıdır. Halihazırda bir kopyanız yoksa, Visual Studio 2022’yi buradan indirin.
Visual Studio 2022’de bir konsol uygulama projesi oluşturun
Öncelikle Visual Studio’da bir .NET Core konsol uygulama projesi oluşturalım. Sisteminizde Visual Studio 2022’nin kurulu olduğunu varsayarak, yeni bir .NET Core konsol uygulama projesi oluşturmak için aşağıda belirtilen adımları izleyin.
- Visual Studio IDE’yi başlatın.
- “Yeni bir proje oluştur” u tıklayın.
- “Yeni proje oluştur” penceresinde, görüntülenen şablonlar listesinden “Konsol Uygulaması”nı seçin.
- Sonrakine tıkla.
- Sonraki gösterilen “Yeni projenizi yapılandırın” penceresinde yeni proje için ad ve konum belirtin.
- “Ek Bilgiler” penceresinde, çalışma zamanı olarak .NET 6.0’ı seçin ve İleri’ye tıklayın.
- Oluştur’u tıklayın.
Bu projeyi aşağıdaki dizi sıkıştırma ve açma işlemlerini göstermek için kullanacağız. Ama önce sıkıştırmadan elde ettiğimiz faydaları ölçmemizi sağlayacak olan BenchmarkDotNet adlı bir kıyaslama paketi kuracağız.
BenchmarkDotNet NuGet paketini kurun
Kıyaslama kodu, uygulamanızın performansını anlamak için gereklidir. Bu yazıda, yöntemlerin performansını izlemek için BenchmarkDotNet’ten yararlanacağız. BenchmarkDotNet’e aşina değilseniz, önce bu makaleyi okumanızı öneririm.
BenchmarkDotNet ile çalışmak için BenchmarkDotNet paketini kurmalısınız. Bunu, Visual Studio 2022 içindeki NuGet Paket Yöneticisi aracılığıyla veya NuGet Paket Yöneticisi Konsolunda aşağıdaki komutu yürüterek yapabilirsiniz:
Install-Package BenchmarkDotNet
C#’daki System.IO.Compression ad alanı
System.IO.Compression ad alanı, dosyaları ve dizeleri sıkıştırma yöntemlerini içerir. İki sıkıştırma algoritması içerir: GZip ve Brotli. Takip eden bu bölümlerde, C#’ta hem GZip hem de Brotli sıkıştırma algoritmalarını kullanarak dize verilerini nasıl sıkıştırıp açabileceğimizi inceleyeceğiz.
Aşağıdaki örneklerde aşağıdaki metni kullanacağız:
string originalString = "To work with BenchmarkDotNet you must install the BenchmarkDotNet package. " +
"You can do this either via the NuGet Package Manager inside the Visual Studio 2019 IDE, " +
"or by executing the Install-Package BenchmarkDotNet command at the NuGet Package Manager Console";
C#’da GZip kullanarak verileri sıkıştırın ve açın
Aşağıdaki kod parçacığı, C#’da GZipStream sınıfını kullanarak verileri nasıl sıkıştırabileceğinizi gösterir. Sıkıştırma yönteminin parametresinin bir bayt dizisi olduğuna dikkat edin.
public static byte[] Compress(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
{
gzipStream.Write(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}
GZip algoritması kullanılarak sıkıştırılmış verileri açmak için aşağıdaki yöntemi kullanabiliriz.
public static byte[] Decompress(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}
GZip sıkıştırma algoritmasını çalıştırma
Yeni oluşturduğumuz GZip sıkıştırma yöntemlerini çalıştırmak için aşağıdaki kod parçasını kullanabilirsiniz.
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = GZipCompressor.Compress(dataToCompress);
string compressedString = Encoding.UTF8.GetString(compressedData);
Console.WriteLine("Length of compressed string: " + compressedString.Length);
byte[] decompressedData = GZipCompressor.Decompress(compressedData);
string deCompressedString = Encoding.UTF8.GetString(decompressedData);
Console.WriteLine("Length of decompressed string: " + deCompressedString.Length);
Yukarıdaki kodu çalıştırdığınızda, konsol penceresinde aşağıdaki çıktıyı göreceksiniz.
Şekil 1. GZip, 259 karakterlik orijinal diziyi 167 karaktere sıkıştırdı.
GZip’in orijinal 259 karakter dizisinden 92 karakteri kırptığını unutmayın. Orijinal dize ve sıkıştırılmış dize aynı olması gerektiğinden, uzunlukları da aynı olmalıdır.
C#’da Brotli kullanarak verileri sıkıştırın ve sıkıştırın
Aşağıdaki kod parçacığı, C#’da BrotliStream sınıfını kullanarak verileri nasıl sıkıştırabileceğinizi gösterir. Yukarıdaki GZip örneğinde olduğu gibi, Sıkıştırma yönteminin parametresinin bir bayt dizisi olduğuna dikkat edin.
public static byte[] Compress(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimal))
{
brotliStream.Write(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}
Ve verileri sıkıştırmak için BrotliStream’i şu şekilde kullanabilirsiniz:
public static byte[] Decompress(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
decompressStream.CopyTo(outputStream);
}
return outputStream.ToArray();
}
}
}
Brotli sıkıştırma algoritmasını çalıştırma
Aşağıdaki kod parçacığı, yukarıda oluşturduğumuz Brotli sıkıştırma yöntemini kullanarak bir dizeyi nasıl sıkıştırabileceğinizi gösterir.
Console.WriteLine("Length of original string: " + originalString.Length);
byte[] dataToCompress = Encoding.UTF8.GetBytes(originalString);
byte[] compressedData = BrotliCompressor.Compress(dataToCompress);
string compressedString = Convert.ToBase64String(compressedData);
Console.WriteLine("Length of compressed string: " + compressedString.Length);
byte[] decompressedData = BrotliCompressor.Decompress(compressedData);
string deCompressedString = Convert.ToBase64String(decompressedData);
Console.WriteLine("Length of decompressed string: " + deCompressedString.Length);
Programı çalıştırdığınızda konsol penceresinde aşağıdaki çıktıyı göreceksiniz.
Şekil 2. Brotli, 259 karakterlik orijinal diziyi 121 karaktere sıkıştırdı.
Gördüğünüz gibi, Brotli, GZip’ten çok daha iyi bir sıkıştırma işi yapıyor. Ancak, aşağıda göreceğimiz gibi, sıkıştırma oranı hikayenin tamamı değildir.
GZip ve Brotli ile asenkron sıkıştırma ve açma
Daha önce kullandığımız sıkıştırma ve açma yöntemlerinin eşzamansız karşılıkları olduğunu unutmayın. GZip algoritmasını kullanan Sıkıştır ve Sıkıştır yöntemlerinin zaman uyumsuz sürümleri şunlardır:
public async static Task<byte[]> CompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
{
await gzipStream.WriteAsync(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}
public async static Task<byte[]> DecompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
await decompressStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}
Ve burada Brotli kullanan Sıkıştır ve Sıkıştır yöntemlerinin eşzamansız sürümleri:
public static async Task<byte[]> CompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionLevel.Optimal))
{
await brotliStream.WriteAsync(bytes, 0, bytes.Length);
}
return memoryStream.ToArray();
}
}
public static async Task<byte[]> DecompressAsync(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var outputStream = new MemoryStream())
{
using (var brotliStream = new BrotliStream(memoryStream, CompressionMode.Decompress))
{
await brotliStream.CopyToAsync(outputStream);
}
return outputStream.ToArray();
}
}
}
C#’da GZip ve Brotli ile sıkıştırma ve açma karşılaştırması
Daha önce oluşturduğumuz konsol uygulama projesinde BenchmarkCompression.cs adında yeni bir dosya oluşturun ve aşağıdaki kodu girin.
[MemoryDiagnoser]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class BenchmarkCompression
{
string originalString = "To work with BenchmarkDotNet you must install the BenchmarkDotNet package. " +
"You can do this either via the NuGet Package Manager inside the Visual Studio 2019 IDE, " +
"or by executing the Install-Package BenchmarkDotNet command at the NuGet Package Manager 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);
}
}
Karşılaştırmaları çalıştırdığınızda, aşağıdaki Şekil 3’te gösterilene benzer bir konsol çıktısı görmelisiniz.
Şekil 3. BenchmarkDotNet sonuçları… GZip kazandı!
Açıkçası, bir sıkıştırma algoritması seçerken dikkate alınan tek şey sıkıştırma oranı değildir. GZip’e kıyasla Brotli kullanarak çok daha iyi sıkıştırma elde edebilmenize rağmen, ek sıkıştırma performans pahasına gelir. GZip, verileri sıkıştırma ve açma konusunda Brotli’den önemli ölçüde daha hızlıdır.
.NET uygulamanızı kıyaslarken, projenizi her zaman yayın modunda çalıştırdığınızdan emin olmalısınız. Bunun nedeni, derleyicinin kodu hata ayıklama ve serbest bırakma modları için farklı şekilde optimize etmesidir. Gelecekteki gönderilerde kıyaslama ve uygulama performansı hakkında söyleyecek daha çok şeyim olacak.
Telif Hakkı © 2022 IDG Communications, Inc.
Kaynak : https://www.infoworld.com/article/3660629/how-to-compress-and-decompress-strings-in-c-sharp.html#tk.rss_all