Created
October 4, 2018 15:53
-
-
Save vexx32/1dc212180b87ecedd6fbcd81b8aa46f8 to your computer and use it in GitHub Desktop.
benchmark for binary parsing in PS Core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////// | |
////////// BENCHMARK RESULTS ////////// | |
/////////////////////////////////////// | |
// * Summary * | |
BenchmarkDotNet=v0.11.1, OS=Windows 10.0.17134.286 (1803/April2018Update/Redstone4) | |
Intel Core i3-3240 CPU 3.40GHz (Ivy Bridge), 1 CPU, 4 logical and 2 physical cores | |
Frequency=3312801 Hz, Resolution=301.8594 ns, Timer=TSC | |
.NET Core SDK=2.1.402 | |
[Host] : .NET Core 2.1.4 (CoreCLR 4.6.26814.03, CoreFX 4.6.26814.02), 64bit RyuJIT | |
Core : .NET Core 2.1.4 (CoreCLR 4.6.26814.03, CoreFX 4.6.26814.02), 64bit RyuJIT | |
Job=Core Runtime=Core | |
Method | Mean | Error | StdDev | Gen 0 | Allocated | | |
----------------- |-----------:|-----------:|----------:|-------:|----------:| | |
ParseWithSpans | 8,716.7 ns | 178.832 ns | 527.29 ns | 2.2430 | 3552 B | | |
ParseWithConvert | 209.1 ns | 4.222 ns | 10.67 ns | 0.0558 | 88 B | | |
// * Warnings * | |
MultimodalDistribution | |
BinaryParse.ParseWithConvert: Core -> It seems that the distribution can have several modes (mValue = 3.13) | |
// * Legends * | |
Mean : Arithmetic mean of all measurements | |
Error : Half of 99.9% confidence interval | |
StdDev : Standard deviation of all measurements | |
Gen 0 : GC Generation 0 collects per 1k Operations | |
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B) | |
1 ns : 1 Nanosecond (0.000000001 sec) | |
// * Diagnostic Output - MemoryDiagnoser * | |
// ***** BenchmarkRunner: End ***** | |
Run time: 00:02:27 (147.79 sec), executed benchmarks: 2 | |
// * Artifacts cleanup * | |
/////////////////////////////////////// | |
/////// CODE USED FOR BENCHMARK /////// | |
/////////////////////////////////////// | |
using System; | |
using System.Numerics; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
namespace Benchmark | |
{ | |
[CoreJob] | |
[MemoryDiagnoser] | |
public class BinaryParse | |
{ | |
private static Random random = new Random(); | |
private readonly string data; | |
public BinaryParse() | |
{ | |
data = Convert.ToString(random.Next(), 2); | |
} | |
[Benchmark] | |
public BigInteger ParseWithSpans() => ParseBinarySpans(data); | |
[Benchmark] | |
public BigInteger ParseWithConvert() => ParseBinaryStrings(data); | |
internal static BigInteger ParseBinarySpans(ReadOnlySpan<char> digits) | |
{ | |
bool unsigned = false; | |
switch (digits.Length) | |
{ | |
case int n when (n <= 8): | |
return parseBinarySpans(digits, unsigned, 8); | |
case int n when (n <= 16): | |
return parseBinarySpans(digits, unsigned, 16); | |
case int n when (n <= 32): | |
return parseBinarySpans(digits, unsigned, 32); | |
case int n when (n <= 64): | |
return parseBinarySpans(digits, unsigned, 64); | |
default: | |
return parseBinarySpans(digits, unsigned); | |
} | |
} | |
private static BigInteger parseBinarySpans(ReadOnlySpan<char> digits, bool unsigned, int padLength = 0) | |
{ | |
unsigned = unsigned || (digits[0] == '0') || digits.Length < padLength; | |
BigInteger value = 0; | |
for (int i = 0; i < digits.Length; i++) | |
{ | |
value += (digits[i] == '1') ? BigInteger.Pow(2, digits.Length - i - 1) : 0; | |
} | |
return unsigned ? value : (value - BigInteger.Pow(2, digits.Length)); | |
} | |
internal static BigInteger ParseBinaryStrings(ReadOnlySpan<char> digits) | |
{ | |
bool unsigned = false; | |
var digitString = new string(digits); | |
switch (digits.Length) | |
{ | |
case int n when (n <= 8): | |
return unsigned ? (BigInteger)Convert.ToByte(digitString, 2) : Convert.ToSByte(digitString, 2); | |
case int n when (n <= 16): | |
return unsigned ? (BigInteger)Convert.ToUInt16(digitString, 2) : Convert.ToInt16(digitString, 2); | |
case int n when (n <= 32): | |
return unsigned ? (BigInteger)Convert.ToUInt32(digitString, 2) : Convert.ToInt32(digitString, 2); | |
case int n when (n <= 64): | |
return unsigned ? (BigInteger)Convert.ToUInt64(digitString, 2) : Convert.ToInt64(digitString, 2); | |
default: | |
return ParseBigBinary(digits, unsigned); | |
} | |
} | |
private static BigInteger ParseBigBinary(ReadOnlySpan<char> digits, bool unsigned) | |
{ | |
BigInteger value = 0; | |
unsigned = unsigned || (digits[0] == '0'); | |
for (int i = 0; i < digits.Length; i++) | |
{ | |
value += (digits[i] == '1') ? BigInteger.Pow(2, digits.Length - i - 1) : 0; | |
} | |
return unsigned ? value : (value - BigInteger.Pow(2, digits.Length)); | |
} | |
} | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var summary = BenchmarkRunner.Run<BinaryParse>(); | |
} | |
} | |
} | |
/////////////////////////////////////// | |
///// END CODE USED FOR BENCHMARK ///// | |
/////////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment