Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/Argon/Utilities/Base64Encoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,23 @@ public static void WriteBase64(this TextWriter writer, ReadOnlySpan<byte> buffer
public static void WriteBase64(this TextWriter writer, ReadOnlySpan<byte> buffer)
{
var charsLine = new char[Base64LineSize];
var index = 0;
do
var bytesLine = ArrayPool<byte>.Shared.Rent(LineSizeInBytes);
try
{
var min = Math.Min(LineSizeInBytes, buffer.Length - index);
var slice = buffer.Slice(index, min);
var written = Convert.ToBase64CharArray(slice.ToArray(), 0, min, charsLine, 0);
writer.Write(charsLine, 0, written);
index += LineSizeInBytes;
} while (index < buffer.Length);
var index = 0;
do
{
var min = Math.Min(LineSizeInBytes, buffer.Length - index);
buffer.Slice(index, min).CopyTo(bytesLine);
var written = Convert.ToBase64CharArray(bytesLine, 0, min, charsLine, 0);
writer.Write(charsLine, 0, written);
index += LineSizeInBytes;
} while (index < buffer.Length);
}
finally
{
ArrayPool<byte>.Shared.Return(bytesLine);
}
}
#endif
}
75 changes: 75 additions & 0 deletions src/ArgonTests/Benchmarks/WriteBase64Benchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) 2007 James Newton-King. All rights reserved.
// Use of this source code is governed by The MIT License,
// as found in the license.md file.

using System.Buffers;
using BenchmarkDotNet.Attributes;

[MemoryDiagnoser]
public class WriteBase64Benchmark
{
const int Base64LineSize = 76;
const int LineSizeInBytes = 57;

byte[] data = null!;

[Params(57, 570, 5700, 57000)]
public int Size { get; set; }

[GlobalSetup]
public void Setup()
{
data = new byte[Size];
new Random(42).NextBytes(data);
}

[Benchmark(Baseline = true)]
public void OldToArray()
{
using var writer = new StringWriter();
WriteBase64Old(writer, data);
}

[Benchmark]
public void NewArrayPool()
{
using var writer = new StringWriter();
WriteBase64New(writer, data);
}

static void WriteBase64Old(TextWriter writer, ReadOnlySpan<byte> buffer)
{
var charsLine = new char[Base64LineSize];
var index = 0;
do
{
var min = Math.Min(LineSizeInBytes, buffer.Length - index);
var slice = buffer.Slice(index, min);
var written = Convert.ToBase64CharArray(slice.ToArray(), 0, min, charsLine, 0);
writer.Write(charsLine, 0, written);
index += LineSizeInBytes;
} while (index < buffer.Length);
}

static void WriteBase64New(TextWriter writer, ReadOnlySpan<byte> buffer)
{
var charsLine = new char[Base64LineSize];
var bytesLine = ArrayPool<byte>.Shared.Rent(LineSizeInBytes);
try
{
var index = 0;
do
{
var min = Math.Min(LineSizeInBytes, buffer.Length - index);
buffer.Slice(index, min).CopyTo(bytesLine);
var written = Convert.ToBase64CharArray(bytesLine, 0, min, charsLine, 0);
writer.Write(charsLine, 0, written);
index += LineSizeInBytes;
} while (index < buffer.Length);
}
finally
{
ArrayPool<byte>.Shared.Return(bytesLine);
}
}
}
2 changes: 1 addition & 1 deletion src/Benchmark.Tests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static void Main(string[] args)
var attribute = (AssemblyFileVersionAttribute)typeof(JsonConvert).Assembly.GetCustomAttribute(typeof(AssemblyFileVersionAttribute))!;
Console.WriteLine($"Json.NET Version: {attribute.Version}");

var switcher = new BenchmarkSwitcher([typeof(WriteEscapedJavaScriptString), typeof(SerializeJTokenList), typeof(ReadQuotedNumbers)]);
var switcher = new BenchmarkSwitcher([typeof(WriteEscapedJavaScriptString), typeof(SerializeJTokenList), typeof(ReadQuotedNumbers), typeof(WriteBase64Benchmark)]);
if (args.Length == 0)
{
switcher.Run(["*"]);
Expand Down
Loading