پشتیبانی از فشردهسازی Zstandard (Zstd) در NET 11.
نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۳/۱۳ ۰۸:۲۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
DeflateStream، GZipStream، ZLibStream و در نسخههای اخیر BrotliStream، ابزارهای قدرتمندی را در اختیار توسعهدهندگان قرار داده است. با این حال، نیاز به الگوریتمی که بتواند تعادلی بینقص میان سرعت فوقالعاده بالا و نسبت فشردهسازی ایدهآل برقرار کند، همواره در پروژههای مقیاسبزرگ احساس میشد.ZstandardStream به این مجموعه اضافه شده است که به ما اجازه میدهد از پتانسیل عظیم الگوریتم Zstandard (یا به اختصار Zstd) به صورت بومی (Native) بدون نیاز به کتابخانههای شخص ثالث استفاده کنیم. در این مقاله، به بررسی ساختار این الگوریتم، قابلیتها، نحوه پیادهسازی و ابزارهای جدید آن در داتنت ۱۱ خواهیم پرداخت.7- (سریعترین حالت با کمترین نرخ فشردهسازی) تا 22 (کندترین حالت اما با بیشترین میزان فشردهسازی) پشتیبانی میکند. حالت پیشفرض این الگوریتم روی سطح 3 تنظیم شده است که توازن بهینهای برای اکثر سناریوهای عمومی فراهم میسازد.جایگاه صنعتی Zstandard: کارایی بالای Zstd باعث شده است که در پروژههای بزرگ جهانی به عنوان استاندارد فشردهسازی انتخاب شود؛ از جمله سیستمفایلهای لینوکس (btrfs و SquashFS)، مدیریت بستههای توزیعهای آرچلینوکس و فدورا، پلتفرم ابری AWS Redshift، سیستم Core Dump در FreeBSD و حتی آرشیو بازیهای کنسول نینتندو سوییچ.
Brotli* کار کرده باشید، استفاده از ابزارهای جدید برای شما بسیار آشنا و ساده خواهد بود. فضای نام System.IO.Compression میزبان چهار تایپ (Type) اصلی جدید است:ZstandardStream: یک کلاس بستهبندی استریم (Stream Wrapper) جهت مدیریت جریانهای دادهای.ZstandardEncoder / ZstandardDecoder: ساختارهایی مبتنی بر Struct، بهینه برای مدیریت حافظه و سازگار با Span.ZstandardDictionary: قابلیتی منحصربهفرد جهت فشردهسازی دادههای کوچک و مکرر با بازدهی بالا.ZstandardCompressionOptions: کلاسی برای تنظیم دقیق کیفیت، اندازه پنجره (Window Size) و ویژگیهای اعتبارسنجی.// Compress (فشردهسازی)
using var output = new MemoryStream();
using (var zstd = new ZstandardStream(output, CompressionMode.Compress))
{
await inputStream.CopyToAsync(zstd);
}
// Decompress (باز کردن فشردهسازی)
using var zstdDecompress = new ZstandardStream(compressedStream, CompressionMode.Decompress);
await zstdDecompress.CopyToAsync(outputStream);ZstandardEncoder و ZstandardDecoder به دلیل عدم تخصیص حافظه اضافی در بخش Heap و هماهنگی با Span، بازدهی به مراتب بالاتری دارد:byte[] source = File.ReadAllBytes("data.bin");
// Compress
int maxLength = ZstandardEncoder.GetMaxCompressedLength(source.Length);
var compressed = new byte[maxLength];
ZstandardEncoder.TryCompress(source, compressed, out int bytesWritten);
// Decompress
int decompressedSize = ZstandardDecoder.GetMaxDecompressedLength(compressed.AsSpan(0, bytesWritten));
var decompressed = new byte[decompressedSize];
ZstandardDecoder.TryDecompress(compressed.AsSpan(0, bytesWritten), decompressed, out int bytesRead);ZstandardCompressionOptions میتوان کیفیت فشردهسازی را به صورت عددی سفارشیسازی کرد. در داتنت، گزینه عمومی CompressionLevel.Fastest به کمترین مقدار عددی و CompressionLevel.SmallestSize به سقف آن یعنی ۲۲ نگاشت میشود:var options = new ZstandardCompressionOptions
{
Quality = 6 // بازه عددی بین 1 تا 22، مقدار پیشفرض 3 است
};
using var zstd = new ZstandardStream(output, options);Program.cs، داتنت به طور خودکار هدر درخواستهای حاوی Accept-Encoding: zstd را شناسایی کرده و پاسخ را فشرده میکند:// Program.cs
builder.Services.AddResponseCompression(x =>
{
x.EnableForHttps = true;
x.Providers.Add<ZstandardCompressionProvider>();
});IDecompressionProvider به همین سادگی مکانیزم معکوس را پیادهسازی و مدیریت میکند.// آموزش دیکشنری از روی نمونهها byte[] allSamples = ...; // الحاق تمام دادههای نمونه به هم int[] lengths = ...; // طول تکتک نمونهها using ZstandardDictionary dict = ZstandardDictionary.TrainFromSamples(allSamples, lengths, maxDictionarySize: 100_000); // فشردهسازی با کمک دیکشنری - هر دو سمت باید از یک دیکشنری یکسان استفاده کنند using var encoder = new ZstandardEncoder(dict); encoder.Compress(payload, compressed, out int consumed, out int written, isFinalBlock: true);
نکته: طبق توصیههای استاندارد، حجم بهینه برای دیکشنری حداکثر ۱۰۰ کیلوبایت است و برای آموزش بهینه آن بهتر است حجم دادههای نمونه حدود ۱۰۰ برابر حجم نهایی دیکشنری (حدود ۱۰ مگابایت داده نمونه واقعی و متناوب) باشد تا بالاترین نرخ بازدهی حاصل شود.