Skip to content

Commit

Permalink
added compression benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
caunt committed Aug 30, 2024
1 parent 4a4e5d3 commit e2632a7
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 1 deletion.
13 changes: 12 additions & 1 deletion Void.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@
<Project Path="src\Void.Proxy.Plugins.ProtocolSupport.Java.v1_7_2_to_1_12_2\Void.Proxy.Plugins.ProtocolSupport.Java.v1_7_2_to_1_12_2.csproj" />
<Project Path="src\Void.Proxy\Void.Proxy.csproj" />
<Properties Name="Visual Studio">
<Property Name="OpenWith" Value="17" />
<Property Name="OpenWith" Value="Visual Studio Version 17" />
</Properties>
<Project Path="G:\Void\src\Void.Benchmarks\Void.Benchmarks.csproj" Type="C#" />
<Project Path="G:\Void\src\Void.NBT\Void.NBT.csproj" />
<Project Path="G:\Void\src\Void.Proxy-before\Void.Proxy-before.csproj" />
<Project Path="G:\Void\src\Void.Proxy.API\Void.Proxy.API.csproj" />
<Project Path="G:\Void\src\Void.Proxy.Plugins.ExamplePlugin\Void.Proxy.Plugins.ExamplePlugin.csproj" />
<Project Path="G:\Void\src\Void.Proxy.Plugins.ModsSupport.Forge\Void.Proxy.Plugins.ModsSupport.Forge.csproj" />
<Project Path="G:\Void\src\Void.Proxy.Plugins.ProtocolSupport.Java.v1_13_to_1_20_1\Void.Proxy.Plugins.ProtocolSupport.Java.v1_13_to_1_20_1.csproj" />
<Project Path="G:\Void\src\Void.Proxy.Plugins.ProtocolSupport.Java.v1_20_2_to_latest\Void.Proxy.Plugins.ProtocolSupport.Java.v1_20_2_to_latest.csproj" />
<Project Path="G:\Void\src\Void.Proxy.Plugins.ProtocolSupport.Java.v1_7_2_to_1_12_2\Void.Proxy.Plugins.ProtocolSupport.Java.v1_7_2_to_1_12_2.csproj" />
<Project Path="G:\Void\src\Void.Proxy\Void.Proxy.csproj" />
<Project Path="src\Void.Benchmarks\Void.Benchmarks.csproj" Type="C#" />
</Solution>
4 changes: 4 additions & 0 deletions src/Void.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using BenchmarkDotNet.Running;
using Void.Benchmarks.Streams;

BenchmarkRunner.Run<Compression>();
126 changes: 126 additions & 0 deletions src/Void.Benchmarks/Streams/Compression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using BenchmarkDotNet.Attributes;
using Microsoft.IO;
using Void.Proxy.API.Network.IO.Messages;
using Void.Proxy.API.Network.IO.Streams.Compression;

namespace Void.Benchmarks.Streams;

public class Compression
{
private static readonly RecyclableMemoryStreamManager MemoryStreamManager = new(new RecyclableMemoryStreamManager.Options
{
BlockSize = 1024,
LargeBufferMultiple = 1024 * 1024,
MaximumBufferSize = 16 * 1024 * 1024,
GenerateCallStacks = false,
AggressiveBufferReturn = true,
MaximumLargePoolFreeBytes = 16 * 1024 * 1024,
MaximumSmallPoolFreeBytes = 100 * 1024
});

private readonly IonicZlibCompressionMessageStream _ionicZlibStream = new() { BaseStream = new MinecraftMemoryStream(), CompressionThreshold = 256 };
private readonly SharpZipLibCompressionMessageStream _sharpZipLibStream = new() { BaseStream = new MinecraftMemoryStream(), CompressionThreshold = 256 };
private byte[] _buffer = [];

[Params(32, 1024)] public int BufferSize { get; set; }

/*
* BenchmarkDotNet v0.14.0, Windows 11 (10.0.22631.4112/23H2/2023Update/SunValley3)
* 12th Gen Intel Core i9-12900KF, 1 CPU, 24 logical and 16 physical cores
* .NET SDK 9.0.100-preview.7.24407.12
* [Host] : .NET 9.0.0 (9.0.24.40507), X64 RyuJIT AVX2 [AttachedDebugger]
* DefaultJob : .NET 9.0.0 (9.0.24.40507), X64 RyuJIT AVX2
*
*
* 1KB buffer (with compression)
*
* | Method | BufferSize | Mean | Error | StdDev |
* |------------------ |----------- |------------:|------------:|----------:|
* | SharpZipLib_Write | 1024 | 25,013.6 us | 384.20 us | 359.38 us |
* | SharpZipLib_Read | 1024 | 1,229.1 us | 24.51 us | 46.04 us |
* | IonicZlib_Write | 1024 | 80,828.7 us | 1,184.75 us | 989.32 us |
* | IonicZlib_Read | 1024 | 5,429.7 us | 108.03 us | 280.79 us |
*
* 32B buffer (without compression)
*
* | Method | BufferSize | Mean | Error | StdDev |
* |------------------ |----------- |------------:|------------:|----------:|
* | SharpZipLib_Write | 32 | 1,081.5 us | 40.94 us | 120.06 us |
* | SharpZipLib_Read | 32 | 947.2 us | 27.13 us | 79.58 us |
* | IonicZlib_Write | 32 | 1,022.6 us | 20.42 us | 35.23 us |
* | IonicZlib_Read | 32 | 928.0 us | 21.75 us | 62.05 us |
*/

[GlobalSetup]
public void GlobalSetup()
{
_buffer = new byte[BufferSize];
Random.Shared.NextBytes(_buffer);
}

[IterationSetup]
public void IterationSetup()
{
var sharpZipLibMemoryStream = (MinecraftMemoryStream)_sharpZipLibStream.BaseStream!;
var ionicZlibMemoryStream = (MinecraftMemoryStream)_ionicZlibStream.BaseStream!;

sharpZipLibMemoryStream.Reset(0);
ionicZlibMemoryStream.Reset(0);

SharpZipLib_Write().GetAwaiter().GetResult();
IonicZlib_Write().GetAwaiter().GetResult();

sharpZipLibMemoryStream.Reset();
ionicZlibMemoryStream.Reset();
}

[Benchmark]
public async ValueTask SharpZipLib_Write()
{
for (var i = 0; i < 1000; i++)
{
var stream = MemoryStreamManager.GetStream();
stream.Write(_buffer);

var message = new CompleteBinaryMessage(stream);
await _sharpZipLibStream.WriteMessageAsync(message);
}
}

[Benchmark]
public async ValueTask SharpZipLib_Read()
{
var sharpZipLibMemoryStream = (MinecraftMemoryStream)_sharpZipLibStream.BaseStream!;
sharpZipLibMemoryStream.Reset();

for (var i = 0; i < 1000; i++)
{
var message = await _sharpZipLibStream.ReadMessageAsync();
}
}

[Benchmark]
public async ValueTask IonicZlib_Write()
{
for (var i = 0; i < 1000; i++)
{
var stream = MemoryStreamManager.GetStream();
stream.Write(_buffer);

var message = new CompleteBinaryMessage(stream);
await _ionicZlibStream.WriteMessageAsync(message);
}
}

[Benchmark]
public async ValueTask IonicZlib_Read()
{
var ionicZlibMemoryStream = (MinecraftMemoryStream)_ionicZlibStream.BaseStream!;
ionicZlibMemoryStream.Reset();

for (var i = 0; i < 1000; i++)
{
var message = await _ionicZlibStream.ReadMessageAsync();
}
}
}
78 changes: 78 additions & 0 deletions src/Void.Benchmarks/Streams/MinecraftMemoryStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Net.Sockets;
using Void.Proxy.API.Network.IO.Streams;

namespace Void.Benchmarks.Streams;

internal class MinecraftMemoryStream : IMinecraftNetworkStream
{
private readonly MemoryStream _memoryStream = new();
public NetworkStream BaseStream => null!;

public void PrependBuffer(Memory<byte> buffer)
{
throw new NotSupportedException();
}

public void Dispose()
{
_memoryStream.Dispose();
}

public async ValueTask DisposeAsync()
{
await _memoryStream.DisposeAsync();
}

public void Flush()
{
_memoryStream.Flush();
}

public async ValueTask FlushAsync(CancellationToken cancellationToken = default)
{
await _memoryStream.FlushAsync(cancellationToken);
}

public void Close()
{
_memoryStream.Close();
}

public int Read(Span<byte> span)
{
return _memoryStream.Read(span);
}

public async ValueTask<int> ReadAsync(Memory<byte> memory, CancellationToken cancellationToken = default)
{
return await _memoryStream.ReadAsync(memory, cancellationToken);
}

public void ReadExactly(Span<byte> span)
{
_memoryStream.ReadExactly(span);
}

public async ValueTask ReadExactlyAsync(Memory<byte> memory, CancellationToken cancellationToken = default)
{
await _memoryStream.ReadExactlyAsync(memory, cancellationToken);
}

public void Write(ReadOnlySpan<byte> span)
{
_memoryStream.Write(span);
}

public async ValueTask WriteAsync(ReadOnlyMemory<byte> memory, CancellationToken cancellationToken = default)
{
await _memoryStream.WriteAsync(memory, cancellationToken);
}

public void Reset(int length = -1)
{
_memoryStream.Position = 0;

if (length >= 0)
_memoryStream.SetLength(length);
}
}
18 changes: 18 additions & 0 deletions src/Void.Benchmarks/Void.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Void.Proxy\Void.Proxy.csproj" />
</ItemGroup>

</Project>

0 comments on commit e2632a7

Please sign in to comment.