Skip to content

Instantly share code, notes, and snippets.

@benaadams
Created November 18, 2015 11:47
Show Gist options
  • Save benaadams/43407df97c69a4ae86e8 to your computer and use it in GitHub Desktop.
Save benaadams/43407df97c69a4ae86e8 to your computer and use it in GitHub Desktop.
AsciiToString benchmark
using BenchmarkDotNet;
using BenchmarkDotNet.Tasks;
namespace AsciiToString
{
[BenchmarkTask(platform: BenchmarkPlatform.X86, jitVersion: BenchmarkJitVersion.LegacyJit)]
[BenchmarkTask(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.LegacyJit)]
[BenchmarkTask(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.RyuJit)]
public class AsciiToString
{
private unsafe static void GetAsciiStringStackA(byte* input, int length)
{
// avoid declaring other local vars, or doing work with stackalloc
// to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
char* output = stackalloc char[length];
GetAsciiStringImplementationA(output, input, length);
}
private unsafe static void GetAsciiStringImplementationA(char* output, byte* input, int length)
{
var outputStart = output;
var i = 0;
for (; i + 3 < length; i += 4)
{
*(output++) = (char)*(input++);
*(output++) = (char)*(input++);
*(output++) = (char)*(input++);
*(output++) = (char)*(input++);
}
for (; i < length; i++)
{
*(output++) = (char)*(input++);
}
//return new string(outputStart, 0, length);
}
private unsafe static void GetAsciiStringStackB(byte* input, int length)
{
// avoid declaring other local vars, or doing work with stackalloc
// to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
char* output = stackalloc char[length];
GetAsciiStringImplementationB(output, input, length);
}
private unsafe static void GetAsciiStringImplementationB(char* output, byte* input, int length)
{
var outputStart = output;
var i = 0;
for (; i + 3 < length; i += 4)
{
*(output) = (char)*(input);
*(output + 1) = (char)*(input + 1);
*(output + 2) = (char)*(input + 2);
*(output + 3) = (char)*(input + 3);
output += 4;
input += 4;
}
for (; i < length; i++)
{
*(output++) = (char)*(input++);
}
//return new string(outputStart, 0, length);
}
private unsafe static void GetAsciiStringStackC(byte* input, int length)
{
// avoid declaring other local vars, or doing work with stackalloc
// to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
char* output = stackalloc char[length];
GetAsciiStringImplementationC(output, input, length);
}
private unsafe static void GetAsciiStringImplementationC(char* output, byte* input, int length)
{
var outputStart = output;
for (var i = 0; i < length; i++)
{
*(output++) = (char)*(input++);
}
//return new string(outputStart, 0, length);
}
private static unsafe void GetAsciiStringStackD(byte[] input, int inputOffset, int length)
{
// avoid declaring other local vars, or doing work with stackalloc
// to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
char* output = stackalloc char[length];
GetAsciiStringImplementationD(output, input, inputOffset, length);
}
private static unsafe void GetAsciiStringImplementationD(char* output, byte[] input, int inputOffset, int length)
{
for (var i = 0; i < length; i++)
{
output[i] = (char)input[inputOffset + i];
}
//return new string(output, 0, length);
}
[Params(1, 2, 8, 64, 512, 1024, 4096, 8192, 16384)]
int MaxCounter = 0;
private byte[] buffer;
[Setup]
public void SetupData()
{
buffer = new byte[MaxCounter];
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe void UnrolledPointer()
{
fixed (byte* input = buffer)
{
GetAsciiStringStackA(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe void UnrolledParallelPointer()
{
fixed (byte* input = buffer)
{
GetAsciiStringStackB(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe void SequentialPointer()
{
fixed (byte* input = buffer)
{
GetAsciiStringStackC(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe void SequentialArray()
{
GetAsciiStringStackD(buffer, 0, MaxCounter);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment