Skip to content

Instantly share code, notes, and snippets.

@benaadams
Last active November 18, 2015 13:33
Show Gist options
  • Select an option

  • Save benaadams/079a1ded2e14bc243fd5 to your computer and use it in GitHub Desktop.

Select an option

Save benaadams/079a1ded2e14bc243fd5 to your computer and use it in GitHub Desktop.
betterer
using BenchmarkDotNet;
using BenchmarkDotNet.Tasks;
namespace AsciiToString
{
[BenchmarkTask(platform: BenchmarkPlatform.X86, jitVersion: BenchmarkJitVersion.LegacyJit)]
[BenchmarkTask(platform: BenchmarkPlatform.X64, jitVersion: BenchmarkJitVersion.RyuJit)]
public class AsciiToString
{
private unsafe static int 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];
return GetAsciiStringImplementationA(output, input, length);
}
private unsafe static int 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);
return *outputStart;
}
private unsafe static int 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];
return GetAsciiStringImplementationB(output, input, length);
}
private unsafe static int 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 *outputStart;
//return new string(outputStart, 0, length);
}
private unsafe static int 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];
return GetAsciiStringImplementationC(output, input, length);
}
private unsafe static int GetAsciiStringImplementationC(char* output, byte* input, int length)
{
var outputStart = output;
for (var i = 0; i < length; i++)
{
*(output++) = (char)*(input++);
}
return *outputStart;
//return new string(outputStart, 0, length);
}
private static unsafe int 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];
return GetAsciiStringImplementationD(output, input, inputOffset, length);
}
private static unsafe int GetAsciiStringImplementationD(char* output, byte[] input, int inputOffset, int length)
{
for (var i = 0; i < length; i++)
{
output[i] = (char)input[inputOffset + i];
}
return output[0];
}
[Params(1, 2, 8, 64, 512, 1024, 4096, 8192, 16384)]
public int MaxCounter = 0;
private byte[] buffer;
[Setup]
public void SetupData()
{
buffer = new byte[MaxCounter];
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe int UnrolledPointer()
{
fixed (byte* input = buffer)
{
return GetAsciiStringStackA(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe int UnrolledParallelPointer()
{
fixed (byte* input = buffer)
{
return GetAsciiStringStackB(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe int SequentialPointer()
{
fixed (byte* input = buffer)
{
return GetAsciiStringStackC(input, MaxCounter);
}
}
[Benchmark]
[OperationsPerInvoke(4)]
public unsafe int SequentialArray()
{
return GetAsciiStringStackD(buffer, 0, MaxCounter);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment