Skip to content

Instantly share code, notes, and snippets.

@DamianEdwards
Created November 5, 2022 04:02
Show Gist options
  • Save DamianEdwards/2450ba44dddd905746741ac265bea71e to your computer and use it in GitHub Desktop.
Save DamianEdwards/2450ba44dddd905746741ac265bea71e to your computer and use it in GitHub Desktop.
GZip a string and base64 encode the result in C# (.NET 7)
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkRunner.Run<Benchmarks>();
//Console.WriteLine("Waiting for profiler then press enter");
//Console.ReadLine();
//var bytesProcessed = 0;
//var benchmarks = new Benchmarks();
//for (int i = 0; i < 100_000; i++)
//{
// var result = benchmarks.NewWay();
// bytesProcessed += result.Length;
//}
//Console.WriteLine($"Bytes processed: {bytesProcessed}");
//Console.WriteLine("Hit Enter to exit");
//Console.ReadLine();
[MemoryDiagnoser]
public class Benchmarks
{
const string input =
"""
Sanctus est dolor tempor vero sed dolore sed sea vel tincidunt ullamcorper et lorem dolore. Eirmod dolor amet sadipscing diam enim zzril iriure. At gubergren dolore odio voluptua euismod ipsum commodo cum dolor dolor vulputate sit eirmod lorem. Magna nonumy nulla magna. Amet dolor sea ea rebum clita liber voluptua elitr esse vero tincidunt elit magna dolore sadipscing takimata eu. Stet kasd dolore gubergren aliquyam tempor sed eleifend takimata dolore amet stet eos kasd sadipscing. Stet sit accusam stet rebum tincidunt eos amet sanctus accusam. Molestie takimata et. Eos tation esse duo tempor. Tempor sed augue et kasd lorem. Sit consetetur dolores stet diam consequat justo et tempor qui sadipscing consequat accusam diam lorem vero ut euismod. Labore stet et est sanctus sadipscing accusam. At vero sadipscing diam tempor sanctus nonumy. Nonummy invidunt aliquam dolor accusam invidunt consetetur invidunt ipsum sadipscing et et takimata et consectetuer accusam minim dolor. Magna vero eirmod erat clita dolor diam facilisis amet sadipscing erat magna. Quis sed elitr dolor esse sed iusto praesent et ut ipsum. Gubergren diam eirmod at sanctus tempor gubergren dolores ipsum ipsum te et sed et amet magna takimata at consetetur. Qui et et et.
Nobis stet consequat dolor clita in invidunt et gubergren takimata dolor eirmod ea takimata dignissim eos. Stet dolore et ut tincidunt erat iriure at duis. Rebum sed invidunt illum eos. Erat lorem et. Sit ipsum diam sed vero. Voluptua erat lorem kasd tempor. Ea et veniam wisi consetetur elitr diam elitr sanctus et et iriure eos facilisi diam sea erat. Invidunt volutpat dolor dolor in id at voluptua gubergren consequat dolor rebum vero ut sanctus. Clita accusam vero et velit invidunt sed magna dolore sed ipsum facilisis dolores dolores dolore ut et lorem. Labore accusam erat dolor dolores. Ea et consetetur nonumy tation duis ea. Ipsum dolor et labore facilisis.
Diam dolores qui veniam et rebum no sadipscing et ea magna sea dolor diam duo labore autem takimata. Est lorem et eros takimata erat in. Dolor sea delenit sit takimata luptatum in. Invidunt gubergren voluptua tation stet gubergren diam veniam liber sed hendrerit sanctus consequat aliquyam quis diam diam augue sit. Vel sea nihil esse tempor et laoreet ut justo aliquip takimata gubergren et et ad vero tempor wisi. Amet rebum diam et iriure accusam eirmod et eirmod minim sadipscing ut amet. Minim consectetuer et adipiscing gubergren eirmod vulputate wisi lorem elitr lorem eos amet justo amet. Vulputate soluta magna ipsum sit lorem lorem invidunt sit rebum.
""";
[Benchmark(Baseline = true)]
public string OriginalWay()
{
var output = input.ToGZipBase64();
return output;
}
[Benchmark]
public string NewWay()
{
var output = input.ToGZipBase64_2();
return output;
}
}
public static class StringExtensions
{
public static string ToGZipBase64(this string input)
{
using var outputStream = new MemoryStream();
using var base64Stream = new CryptoStream(outputStream, new ToBase64Transform(), CryptoStreamMode.Write);
using var gzipStream = new GZipStream(base64Stream, CompressionMode.Compress);
using var writer = new StreamWriter(gzipStream);
writer.Write(input);
writer.Flush();
gzipStream.Flush();
outputStream.Position = 0;
var reader = new StreamReader(outputStream);
var output = reader.ReadToEnd();
return output;
}
public static string ToGZipBase64_2(this string input)
{
// string->utf8 bytes->MemoryStream->GZip->MemoryStream->base64-> string
var utf8bytes = ArrayPool<byte>.Shared.Rent(Encoding.UTF8.GetByteCount(input));
var inputBytesLength = Encoding.UTF8.GetBytes(input, utf8bytes);
var outputBuffer = ArrayPool<byte>.Shared.Rent(utf8bytes.Length);
var outputStream = new MemoryStream(outputBuffer);
using var gzipStream = new GZipStream(outputStream, CompressionMode.Compress);
gzipStream.Write(utf8bytes.AsSpan()[..inputBytesLength]);
gzipStream.Flush();
var output = Convert.ToBase64String(outputBuffer.AsSpan()[..(int)outputStream.Position]);
ArrayPool<byte>.Shared.Return(utf8bytes);
ArrayPool<byte>.Shared.Return(outputBuffer);
return output;
}
}
// * Summary *
BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.755)
12th Gen Intel Core i9-12900KF, 1 CPU, 24 logical and 16 physical cores
.NET SDK=7.0.100
[Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
|------------ |---------:|---------:|---------:|---------:|------:|--------:|-------:|-------:|----------:|------------:|
| OriginalWay | 23.46 us | 0.453 us | 0.445 us | 23.53 us | 1.00 | 0.00 | 0.9766 | 0.1221 | 15.41 KB | 1.00 |
| NewWay | 20.54 us | 0.475 us | 1.400 us | 20.97 us | 0.89 | 0.06 | 0.1221 | - | 2.05 KB | 0.13 |
// * Hints *
Outliers
Benchmarks.OriginalWay: Default -> 1 outlier was detected (22.27 us)
Benchmarks.NewWay: Default -> 12 outliers were detected (16.75 us..18.10 us)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment