diff --git a/src/benchmarks/Benchmarks.csproj b/src/benchmarks/Benchmarks.csproj index 506c47bd9bc..8de0582982b 100644 --- a/src/benchmarks/Benchmarks.csproj +++ b/src/benchmarks/Benchmarks.csproj @@ -14,7 +14,7 @@ - + @@ -53,6 +53,7 @@ + diff --git a/src/benchmarks/Harness/TooManyTestCasesValidator.cs b/src/benchmarks/Harness/TooManyTestCasesValidator.cs new file mode 100644 index 00000000000..b0c17e9c11d --- /dev/null +++ b/src/benchmarks/Harness/TooManyTestCasesValidator.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Validators; + +namespace Benchmarks +{ + /// + /// we need to tell our users that having more than 20 test cases per benchmark is a VERY BAD idea + /// + public class TooManyTestCasesValidator : IValidator + { + private const int Limit = 16; + + public static readonly IValidator FailOnError = new TooManyTestCasesValidator(); + + public bool TreatsWarningsAsErrors => true; + + public IEnumerable Validate(ValidationParameters validationParameters) + { + var byDescriptor = validationParameters.Benchmarks.GroupBy(benchmark => benchmark.Descriptor); // descriptor = type + method + + return byDescriptor.Where(benchmarkCase => benchmarkCase.Count() > Limit).Select(group => + new ValidationError( + isCritical: true, + message: $"{group.Key.Type.Name}.{group.Key.WorkloadMethod.Name} has {group.Count()} test cases. It MUST NOT have more than {Limit} test cases. We don't have inifinite amount of time to run all the benchmarks!!", + benchmarkCase: group.First())); + } + } +} \ No newline at end of file diff --git a/src/benchmarks/Program.cs b/src/benchmarks/Program.cs index d76fb287076..b6cd13cdbc7 100644 --- a/src/benchmarks/Program.cs +++ b/src/benchmarks/Program.cs @@ -68,6 +68,8 @@ private static IConfig GetConfig(Options options) config = config.With(JsonExporter.Full); // make sure we export to Json (for BenchView integration purpose) config = config.With(StatisticColumn.Median, StatisticColumn.Min, StatisticColumn.Max); + + config = config.With(TooManyTestCasesValidator.FailOnError); return config; } diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Array.cs b/src/benchmarks/corefx/System.Runtime/Perf.Array.cs new file mode 100644 index 00000000000..5660cea3320 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Array.cs @@ -0,0 +1,273 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; + +namespace System.Tests +{ + public class Perf_Array + { + private static int[] s_arr; + private static Array s_arr1; + private static Array s_arr2; + private static Array s_arr3; + private static Array _destinationArray; + private byte[][] _byteArrays; + + private const int MAX_ARRAY_SIZE = 4096; + + private const int OldSize = 42; + private const int NewSize = 41; + private const int ByteArraysCount = 2_000_000; + + private static readonly int s_DIM_1 = MAX_ARRAY_SIZE; + private static readonly int s_DIM_2 = (int) Math.Pow(MAX_ARRAY_SIZE, (1.0 / 2.0)); + private static readonly int s_DIM_3 = (int) (Math.Pow(MAX_ARRAY_SIZE, (1.0 / 3.0)) + .001); + + [Benchmark] + public Array ArrayCreate1D() => Array.CreateInstance(typeof(int), s_DIM_1); + + [Benchmark] + public Array ArrayCreate2D() => Array.CreateInstance(typeof(int), s_DIM_2, s_DIM_2); + + [Benchmark] + public Array ArrayCreate3D() => Array.CreateInstance(typeof(int), s_DIM_3, s_DIM_3, s_DIM_3); + + [GlobalSetup(Target = nameof(ArrayAssign1D))] + public void SetupArrayAssign1D() => s_arr1 = Array.CreateInstance(typeof(int), s_DIM_1); + + [Benchmark] + public void ArrayAssign1D() + { + for (int j = 0; j < s_DIM_1; j++) + { + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + s_arr1.SetValue(j, j); + } + } + + [GlobalSetup(Target = nameof(ArrayAssign2D))] + public void SetupArrayAssign2D() => s_arr2 = Array.CreateInstance(typeof(int), s_DIM_2, s_DIM_2); + + [Benchmark] + public void ArrayAssign2D() + { + for (int j = 0; j < s_DIM_2; j++) + { + for (int k = 0; k < s_DIM_2; k++) + { + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + s_arr2.SetValue(j + k, j, k); + } + } + } + + [GlobalSetup(Target = nameof(ArrayAssign3D))] + public void SetupArrayAssign3D() => s_arr3 = Array.CreateInstance(typeof(int), s_DIM_3, s_DIM_3, s_DIM_3); + + [Benchmark] + public void ArrayAssign3D() + { + for (int j = 0; j < s_DIM_3; j++) + { + for (int k = 0; k < s_DIM_3; k++) + { + for (int l = 0; l < s_DIM_3; l++) + { + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + s_arr3.SetValue(j + k + l, j, k, l); + } + } + } + } + + [GlobalSetup(Target = nameof(ArrayRetrieve1D))] + public void SetupArrayRetrieve1D() + { + s_arr1 = Array.CreateInstance(typeof(int), s_DIM_1); + + for (int i = 0; i < s_DIM_1; i++) + s_arr1.SetValue(i, i); + } + + [Benchmark] + public int ArrayRetrieve1D() + { + int value = default; + + for (int j = 0; j < s_DIM_1; j++) + { + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + value += (int) s_arr1.GetValue(j); + } + + return value; + } + + [GlobalSetup(Target = nameof(ArrayRetrieve2D))] + public void SetupArrayRetrieve2D() + { + s_arr2 = Array.CreateInstance(typeof(int), s_DIM_2, s_DIM_2); + + for (int i = 0; i < s_DIM_2; i++) + { + for (int j = 0; j < s_DIM_2; j++) + s_arr2.SetValue(i + j, i, j); + } + } + + [Benchmark] + public int ArrayRetrieve2D() + { + int value = default; + + for (int j = 0; j < s_DIM_2; j++) + { + for (int k = 0; k < s_DIM_2; k++) + { + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + value += (int) s_arr2.GetValue(j, k); + } + } + + return value; + } + + [GlobalSetup(Target = nameof(ArrayRetrieve3D))] + public void SetupArrayRetrieve3D() + { + s_arr3 = Array.CreateInstance(typeof(int), s_DIM_3, s_DIM_3, s_DIM_3); + + for (int i = 0; i < s_DIM_3; i++) + { + for (int j = 0; j < s_DIM_3; j++) + { + for (int k = 0; k < s_DIM_3; k++) + s_arr3.SetValue(i + j + k, i, j, k); + } + } + } + + [Benchmark] + public int ArrayRetrieve3D() + { + int value = default; + + for (int j = 0; j < s_DIM_3; j++) + { + for (int k = 0; k < s_DIM_3; k++) + { + for (int l = 0; l < s_DIM_3; l++) + { + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + value += (int) s_arr3.GetValue(j, k, l); + } + } + } + + return value; + } + + [GlobalSetup(Target = nameof(ArrayCopy2D))] + public void SetupArrayCopy2D() + { + _destinationArray = Array.CreateInstance(typeof(int), s_DIM_2, s_DIM_2); + s_arr2 = Array.CreateInstance(typeof(int), s_DIM_2, s_DIM_2); + + for (int i = 0; i < s_DIM_2; i++) + { + for (int j = 0; j < s_DIM_2; j++) + s_arr2.SetValue(i + j, i, j); + } + } + + [Benchmark] + public void ArrayCopy2D() => Array.Copy(s_arr2, _destinationArray, s_DIM_2 * s_DIM_2); + + [GlobalSetup(Target = nameof(ArrayCopy3D))] + public void SetupArrayCopy3D() + { + _destinationArray = Array.CreateInstance(typeof(int), s_DIM_3, s_DIM_3, s_DIM_3); + s_arr3 = Array.CreateInstance(typeof(int), s_DIM_3, s_DIM_3, s_DIM_3); + + for (int i = 0; i < s_DIM_3; i++) + { + for (int j = 0; j < s_DIM_3; j++) + { + for (int k = 0; k < s_DIM_3; k++) + { + s_arr3.SetValue(i + j + k, i, j, k); + } + } + } + } + + [Benchmark] + public void ArrayCopy3D() => Array.Copy(s_arr3, _destinationArray, s_DIM_3 * s_DIM_3 * s_DIM_3); + + [IterationSetup(Target = nameof(ArrayResize))] + public void SetupArrayResizeIteration() + { + _byteArrays = new byte[ByteArraysCount][]; + for (int i = 0; i < _byteArrays.Length; i++) + _byteArrays[i] = new byte[OldSize]; + } + + [Benchmark(OperationsPerInvoke = ByteArraysCount)] + public void ArrayResize() + { + for (int i = 0; i < _byteArrays.Length; i++) + Array.Resize(ref _byteArrays[i], NewSize); + } + } +} \ No newline at end of file diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Boolean.cs b/src/benchmarks/corefx/System.Runtime/Perf.Boolean.cs new file mode 100644 index 00000000000..15317e3cf17 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Boolean.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Boolean + { + [Benchmark(Description = "Parse")] + public bool Parse_str() => bool.Parse(bool.TrueString); + + [Benchmark(Description = "ToString")] + public string ToString_() => true.ToString(); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Char.cs b/src/benchmarks/corefx/System.Runtime/Perf.Char.cs new file mode 100644 index 00000000000..21d04382da3 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Char.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Globalization; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Char + { + public static IEnumerable Char_ChangeCase_MemberData() + { + yield return new object[] { 'A', new CultureInfo("en-US") }; // ASCII upper case + yield return new object[] { 'a', new CultureInfo("en-US") }; // ASCII lower case + yield return new object[] { '\u0130', new CultureInfo("en-US") }; // non-ASCII, English + yield return new object[] { '\u4F60', new CultureInfo("zh-Hans") }; // non-ASCII, Chinese + } + + [Benchmark] + [ArgumentsSource(nameof(Char_ChangeCase_MemberData))] + public char Char_ToLower(char c, CultureInfo cultureName) => char.ToLower(c, cultureName); // the argument is called "cultureName" instead of "culture" to keep benchmark ID in BenchView, do NOT rename it + + [Benchmark] + [ArgumentsSource(nameof(Char_ChangeCase_MemberData))] + public char Char_ToUpper(char c, CultureInfo cultureName)=> char.ToUpper(c, cultureName); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.DateTime.cs b/src/benchmarks/corefx/System.Runtime/Perf.DateTime.cs new file mode 100644 index 00000000000..6e036ce0546 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.DateTime.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_DateTime + { + DateTime date1 = new DateTime(1996, 6, 3, 22, 15, 0); + DateTime date2 = new DateTime(1996, 12, 6, 13, 2, 0); + + [Benchmark] + public DateTime GetNow() => DateTime.Now; + + [Benchmark] + public DateTime GetUtcNow() => DateTime.UtcNow; + + [Benchmark(Description = "ToString")] + public string ToString_str() => date1.ToString("g"); + + [Benchmark] + public TimeSpan op_Subtraction() => date1 - date2; + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Double.cs b/src/benchmarks/corefx/System.Runtime/Perf.Double.cs new file mode 100644 index 00000000000..59f5bbbaa5a --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Double.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Double + { + private readonly decimal decimalNum = new decimal(1.23456789E+5); + + private readonly double[] _testCases = { double.MinValue, 12345.0 /* same value used by other tests to compare the perf */, double.MaxValue }; + private readonly string[] _formats = { "R", "G", "G17", "E", "F50" }; + + public IEnumerable DefaultToStringArguments() + => _testCases.Select(value => new object[] {value, 100_000}); + + [Benchmark] + [ArgumentsSource(nameof(DefaultToStringArguments))] + public string DefaultToString(double number, int innerIterations) // innerIterations argument is not used anymore but kept to preserve benchmark ID, do NOT remove it + => number.ToString(); + + public IEnumerable ToStringWithCultureInfoArguments() + => _testCases.Select(value => new object[] { new CultureInfo("zh"), value, 100_000}); + + [Benchmark] + [ArgumentsSource(nameof(ToStringWithCultureInfoArguments))] + public string ToStringWithCultureInfo(CultureInfo cultureName, double number, int innerIterations) // the argument is called "cultureName" instead of "culture" to keep benchmark ID in BenchView, do NOT rename it + => number.ToString(cultureName); + + public IEnumerable ToStringWithFormat_TestData() + => _formats.SelectMany(format => _testCases.Select(value => new object[] {format, value, 2_000_000})); + + [Benchmark] + [ArgumentsSource(nameof(ToStringWithFormat_TestData))] + public string ToStringWithFormat(string format, double number, int innerIterations) // innerIterations argument is not used anymore but kept to preserve benchmark ID, do NOT remove it + => number.ToString(format); + + [Benchmark] + public string Decimal_ToString() => decimalNum.ToString(); + } +} \ No newline at end of file diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Enum.cs b/src/benchmarks/corefx/System.Runtime/Perf.Enum.cs new file mode 100644 index 00000000000..3100f1dc4ea --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Enum.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Enum + { + private enum testEnum + { + Red = 1, + Blue = 2 + } + + [Benchmark] + public object Parse() => Enum.Parse(typeof(testEnum), "Red"); + + [Benchmark] + public bool TryParseGeneric() => Enum.TryParse("Red", out _); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Guid.cs b/src/benchmarks/corefx/System.Runtime/Perf.Guid.cs new file mode 100644 index 00000000000..658c20dcc3a --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Guid.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Guid + { + const string guidStr = "a8a110d5-fc49-43c5-bf46-802db8f843ff"; + + [Benchmark] + public Guid NewGuid() => Guid.NewGuid(); + + [Benchmark] + public Guid ctor_str() => new Guid(guidStr); + } +} \ No newline at end of file diff --git a/src/benchmarks/corefx/System.Runtime/Perf.HashCode.cs b/src/benchmarks/corefx/System.Runtime/Perf.HashCode.cs new file mode 100644 index 00000000000..b7ee4a75a39 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.HashCode.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_HashCode + { + private static volatile int _valueStorage; + + // Prevents the jitter from eliminating code that + // we want to test. + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void DontDiscard(int value) + { + _valueStorage = value; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static int DontFold(int value) + { + return value + _valueStorage; + } + + [Benchmark] + public int Add() + { + var hc = new HashCode(); + for (int j = 0; j < 100; j++) + { + hc.Add(j); hc.Add(j); hc.Add(j); + hc.Add(j); hc.Add(j); hc.Add(j); + hc.Add(j); hc.Add(j); hc.Add(j); + } + return hc.ToHashCode(); + } + + + [Benchmark] + public void Combine_1() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i))); + } + } + + + [Benchmark] + public void Combine_2() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_3() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_4() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_5() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_6() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_7() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + + [Benchmark] + public void Combine_8() + { + for (int i = 0; i < 10000; i++) + { + DontDiscard(HashCode.Combine( + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i), + DontFold(i))); + } + } + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Int32.cs b/src/benchmarks/corefx/System.Runtime/Perf.Int32.cs new file mode 100644 index 00000000000..4d02273b5ff --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Int32.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Int32 + { + private char[] _destination = new char[int.MinValue.ToString().Length]; + + public IEnumerable Int32Values => new object[] + { + int.MinValue, + (int)12345, // same value used by other tests to compare the perf + int.MaxValue + }; + + public IEnumerable StringValues => Int32Values.Select(value => value.ToString()).ToArray(); + + [Benchmark] + [ArgumentsSource(nameof(Int32Values))] + public string ToString(int value) => value.ToString(); + +#if NETCOREAPP2_1 + [Benchmark] + [ArgumentsSource(nameof(StringValues))] + public int Parse(string value) => int.Parse(value.AsSpan()); + + [Benchmark] + [ArgumentsSource(nameof(Int32Values))] + public bool TryFormat(int value) => value.TryFormat(new Span(_destination), out _); +#endif + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Int64.cs b/src/benchmarks/corefx/System.Runtime/Perf.Int64.cs new file mode 100644 index 00000000000..ed23e18665b --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Int64.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Int64 + { + private char[] _destination = new char[long.MinValue.ToString().Length]; + + public IEnumerable StringValues => Int64Values.Select(value => value.ToString()).ToArray(); + + public IEnumerable Int64Values => new object[] + { + long.MinValue, + (long)12345, // same value used by other tests to compare the perf + long.MaxValue, + }; + + [Benchmark] + [ArgumentsSource(nameof(Int64Values))] + public string ToString(long value) => value.ToString(); + +#if NETCOREAPP2_1 + [Benchmark] + [ArgumentsSource(nameof(Int64Values))] + public bool TryFormat(long value) => value.TryFormat(new Span(_destination), out _); + + [Benchmark] + [ArgumentsSource(nameof(StringValues))] + public long Parse(string value) => long.Parse(value.AsSpan()); +#endif + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.IntPtr.cs b/src/benchmarks/corefx/System.Runtime/Perf.IntPtr.cs new file mode 100644 index 00000000000..132465154f0 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.IntPtr.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_IntPtr + { + IntPtr ptr1 = new IntPtr(0); + IntPtr ptr2 = new IntPtr(0); + + [Benchmark] + public IntPtr ctor_int32() => new IntPtr(0); + + [Benchmark] + public bool op_Equality_IntPtr_IntPtr() => ptr1 == ptr2; + } +} \ No newline at end of file diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Object.cs b/src/benchmarks/corefx/System.Runtime/Perf.Object.cs new file mode 100644 index 00000000000..bb8cfa393c5 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Object.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Object + { + object obj = new object(); + + [Benchmark] + public object ctor() => new object(); + + [Benchmark(Description = "GetType")] + public Type GetType_() => obj.GetType(); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.String.cs b/src/benchmarks/corefx/System.Runtime/Perf.String.cs new file mode 100644 index 00000000000..974d953374d --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.String.cs @@ -0,0 +1,354 @@ +using System.Collections.Generic; +using System.Globalization; +using BenchmarkDotNet.Attributes; + +namespace System.Tests +{ + public class Perf_String + { + public static IEnumerable TestStringSizes() + { + yield return new StringArguments(100); + yield return new StringArguments(1000); + } + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public char[] GetChars(StringArguments size) // the argument is called "size" to keep the old benchmark ID, do NOT rename it + => size.TestString1.ToCharArray(); + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public string Concat_str_str(StringArguments size) + => string.Concat(size.TestString1, size.TestString2); + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public string Concat_str_str_str(StringArguments size) + => string.Concat(size.TestString1, size.TestString2, size.TestString3); + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public string Concat_str_str_str_str(StringArguments size) + => string.Concat(size.TestString1, size.TestString2, size.TestString3, size.TestString4); + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public bool Contains(StringArguments size) + => size.TestString1.Contains(size.Q3); + + [Benchmark] + [ArgumentsSource(nameof(TestStringSizes))] + public bool StartsWith(StringArguments size) + => size.TestString1.StartsWith(size.Q1); + + [Benchmark] + [Arguments("")] + [Arguments("TeSt!")] + [Arguments("dzsdzsDDZSDZSDZSddsz")] + public int GetHashCode(string s) + => s.GetHashCode(); + + [Benchmark] + [Arguments("Test", 2, " Test")] + [Arguments("dzsdzsDDZSDZSDZSddsz", 7, "Test")] + public string Insert(string s1, int i, string s2) + => s1.Insert(i, s2); + + [Benchmark] + [Arguments(18)] + [Arguments(2142)] + public string PadLeft(int n) + => "a".PadLeft(n); + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", 0)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 7)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 10)] + public string Remove_Int(string s, int i) + => s.Remove(i); + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", 0, 8)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 7, 4)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 10, 1)] + public string Remove_IntInt(string s, int i1, int i2) + => s.Remove(i1, i2); + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", 0)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 7)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 10)] + public string Substring_Int(string s, int i) + => s.Substring(i); + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", 0, 8)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 7, 4)] + [Arguments("dzsdzsDDZSDZSDZSddsz", 10, 1)] + public string Substring_IntInt(string s, int i1, int i2) + => s.Substring(i1, i2); + + [Benchmark] + [Arguments("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", new char[] { ' ' }, StringSplitOptions.None)] + [Arguments("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)] + [Arguments("ABCDEFGHIJKLMNOPQRSTUVWXYZ", new char[]{' '}, StringSplitOptions.None)] + [Arguments("ABCDEFGHIJKLMNOPQRSTUVWXYZ", new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)] + public string[] Split(string s, char[] arr, StringSplitOptions options) + => s.Split(arr, options); + + [Benchmark] + [Arguments("Test")] + [Arguments(" Test")] + [Arguments("Test ")] + [Arguments(" Te st ")] + public string Trim(string s) + => s.Trim(); + + [Benchmark] + [Arguments("Test")] + [Arguments(" Test")] + public string TrimStart(string s) + => s.TrimStart(); + + [Benchmark] + [Arguments("Test")] + [Arguments("Test ")] + public string TrimEnd(string s) + => s.TrimEnd(); + + [Benchmark] + [Arguments("Test", new [] {' ', (char) 8197})] + [Arguments(" Test", new [] {' ', (char) 8197})] + [Arguments("Test ", new [] {' ', (char) 8197})] + [Arguments(" Te st ", new [] {' ', (char) 8197})] + public string Trim_CharArr(string s, char[] c) + => s.Trim(c); + + [Benchmark] + [Arguments("Test", new [] {' ', (char) 8197})] + [Arguments(" Test", new [] {' ', (char) 8197})] + public string TrimStart_CharArr(string s, char[] c) + => s.TrimStart(c); + + [Benchmark] + [Arguments("Test", new [] {' ', (char) 8197})] + [Arguments("Test ", new [] {' ', (char) 8197})] + public string TrimEnd_CharArr(string s, char[] c) + => s.TrimEnd(c); + + [Benchmark] + [Arguments("This is a very nice sentence", 'z', 'y')] // 'z' does not exist in the string + [Arguments("This is a very nice sentence", 'i', 'I')] // 'i' occuress 3 times in the string + public string Replace_Char(string text, char oldChar, char newChar) + => text.Replace(oldChar, newChar); + + [Benchmark] + [Arguments("This is a very nice sentence", "bad", "nice")] // there are no "bad" words in the string + [Arguments("This is a very nice sentence", "nice", "bad")] // there are is one "nice" word in the string + public string Replace_String(string text, string oldValue, string newValue) + => text.Replace(oldValue, newValue); + + private static readonly string s_longString = + "\nFamiliar \nFoesPhelps \nfaces rival Crocker in tonight's 100m butterfly finalPhelps \ndenies doping allegationsVideo: \nSixth gold for PhelpsFamiliar \nFoesMichael \nPhelps, right, will face world-record holder Ian Crocker in the 100-meter \nbutterfly final in Beijing.Latest \nnewsVideo \nhighlightsFamiliar \nFoesPhelps \nfaces rival Crocker in tonight's 100m butterfly finalPhelps \ndenies doping allegationsVideo: \nSixth gold for PhelpsFamiliar \nFoesMichael \nPhelps, right, will face world-record holder Ian Crocker in the 100-meter \nbutterfly final in Beijing.Latest \nnewsVideo \nhighlightsLatest News From NBCOlympics.comSurprise \nU.S. medal as track beginsInside \nthe art of Liukin's epic goldBlake \nloses, blasts opponent's ethicsU.S. \nfumes after loss to Cuba#Click to see up-to-the-minute news \n& results from NBCOlympics.comExclusive \nVideoNastia \nNails ItSee \nLiukin's routinesBeach \nVolleyballMisty, \nKerri survive scareBoxingBiggest \nhits from Day 6For an \nenhanced Olympics experience, download Microsoft Silverlight \n2ScheduleMedal \nCountVideoAthletesPhotosOlympics \nTV listingsAll-time \nmedal standingsPhotos: \nMost popular galleriesVideo: \nLatest Olympic highlightsOlympics \nTV listingsAll-time \nmedal standingsPhotos: \nMost popular galleriesVideo: \nLatest Olympic highlightsOlympics \nTV listingsAll-time \nmedal standingsPhotos: \nMost popular galleriesVideo: \nLatest Olympic highlights"; + + private static readonly string s_tagName = " s_longString.IndexOf(s_tagName, options); + + [Benchmark] + [Arguments(StringComparison.CurrentCultureIgnoreCase)] + [Arguments(StringComparison.Ordinal)] + [Arguments(StringComparison.OrdinalIgnoreCase)] + public int LastIndexOf(StringComparison options) + => s_longString.LastIndexOf(s_tagName, options); + + private CultureInfo _cultureInfo; + + [Benchmark] + [Arguments("The quick brown fox", "The quick brown fox")] + [Arguments("Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick brown f\u00f2x")] + public int Compare_Culture_invariant(string s1, string s2) + => CultureInfo.InvariantCulture.CompareInfo.Compare(s1, s2, CompareOptions.None); + + [GlobalSetup(Target = nameof(Compare_Culture_en_us))] + public void SetupCompare_Culture_en_us() => _cultureInfo = new CultureInfo("en-us"); + + [Benchmark] + [Arguments("The quick brown fox", "The quick brown fox")] + [Arguments("Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick brown f\u00f2x")] + public int Compare_Culture_en_us(string s1, string s2) + => _cultureInfo.CompareInfo.Compare(s1, s2, CompareOptions.None); + + [GlobalSetup(Target = nameof(Compare_Culture_ja_jp))] + public void SetupCompare_Culture_ja_jp() => _cultureInfo = new CultureInfo("ja-jp"); + + [Benchmark] + [Arguments("The quick brown fox", "The quick brown fox")] + [Arguments("Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick brown f\u00f2x")] + public int Compare_Culture_ja_jp(string s1, string s2) + => _cultureInfo.CompareInfo.Compare(s1, s2, CompareOptions.None); + + [Benchmark] + [Arguments(new [] {"The quick brown fox", "THE QUICK BROWN FOX"}, StringComparison.CurrentCultureIgnoreCase)] + [Arguments(new [] {"The quick brown fox", "THE QUICK BROWN FOX"}, StringComparison.Ordinal)] + [Arguments(new [] {"The quick brown fox", "THE QUICK BROWN FOX"}, StringComparison.OrdinalIgnoreCase)] + [Arguments(new [] {"Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick BROWN f\u00f2x"}, StringComparison.CurrentCultureIgnoreCase)] + [Arguments(new [] {"Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick BROWN f\u00f2x"}, StringComparison.Ordinal)] + [Arguments(new [] {"Th\u00e9 quick brown f\u00f2x", "Th\u00e9 quick BROWN f\u00f2x"}, StringComparison.OrdinalIgnoreCase)] + public int Compare(string[] strings, StringComparison comparison) // we should have two separate string arguments but we keep it that way to don't change the ID of the benchmark + => string.Compare(strings[0], strings[1], comparison); + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", "dzsdzsDDZSDZSDZSddsz")] + public bool Equality(string s1, string s2) + => s1 == s2; + + [Benchmark] + [Arguments("dzsdzsDDZSDZSDZSddsz", "dzsdzsDDZSDZSDZSddsz")] + public bool Equals(string s1, string s2) + => s1.Equals(s2); + + [Benchmark] + [Arguments("Testing {0}, {0:C}, {0:D5}, {0:E} - {0:F4}{0:G}{0:N} {0:X} !!", 8)] + [Arguments("Testing {0}, {0:C}, {0:E} - {0:F4}{0:G}{0:N} , !!", 3.14159)] + public string Format_OneArg(string s, object o) + => string.Format(s, o); + + [Benchmark] + public string Format_MultipleArgs() + => string.Format("More testing: {0} {1} {2} {3} {4} {5}{6} {7}", '1', "Foo", "Foo", "Foo", "Foo", "Foo", "Foo", "Foo"); + + [Benchmark] + [Arguments('1', "Foo")] + public string Interpolation_MultipleArgs(char c, string s) + => $"More testing: {c} {s} {s} {s} {s} {s}{s} {s}"; + + [Benchmark] + [Arguments("TeSt")] + [Arguments("TEST")] + [Arguments("test")] + public string ToUpper(string s) + => s.ToUpper(); + + [Benchmark] + [Arguments("TeSt")] + [Arguments("TEST")] + [Arguments("test")] + public string ToUpperInvariant(string s) + => s.ToUpperInvariant(); + + [Benchmark] + [Arguments("TeSt")] + [Arguments("TEST")] + [Arguments("test")] + public string ToLower(string s) + => s.ToLower(); + + [Benchmark] + [Arguments("TeSt")] + [Arguments("TEST")] + [Arguments("test")] + public string ToLowerInvariant(string s) + => s.ToLowerInvariant(); + + private static readonly string _s1 = + "ddsz dszdsz \t dszdsz a\u0300\u00C0 \t Te st \u0400Te \u0400st\u0020\u00A0\u2000\u2001\u2002\u2003\u2004\u2005\t Te\t \tst \t\r\n\u0020\u00A0\u2000\u2001\u2002\u2003\u2004\u2005"; + + [Benchmark] + public int IndexerCheckBoundCheckHoist() + { + string s1 = _s1; + int counter = 0; + + int strLength = _s1.Length; + + for (int j = 0; j < strLength; j++) + { + counter += s1[j]; + } + + return counter; + } + + [Benchmark] + public int IndexerCheckLengthHoisting() + { + string s1 = _s1; + int counter = 0; + + for (int j = 0; j < s1.Length; j++) + { + counter += s1[j]; + } + + return counter; + } + + [Benchmark] + public int IndexerCheckPathLength() + { + string s1 = _s1; + int counter = 0; + + for (int j = 0; j < s1.Length; j++) + { + counter += getStringCharNoInline(s1, j); + } + + return counter; + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + private static char getStringCharNoInline(string str, int index) + { + return str[index]; + } + +#if NETCOREAPP2_1 + [Benchmark] + [Arguments("This is a very nice sentence", "bad", StringComparison.CurrentCultureIgnoreCase)] + [Arguments("This is a very nice sentence", "bad", StringComparison.Ordinal)] + [Arguments("This is a very nice sentence", "bad", StringComparison.OrdinalIgnoreCase)] + [Arguments("This is a very nice sentence", "nice", StringComparison.CurrentCultureIgnoreCase)] + [Arguments("This is a very nice sentence", "nice", StringComparison.Ordinal)] + [Arguments("This is a very nice sentence", "nice", StringComparison.OrdinalIgnoreCase)] + public bool Contains(String text, String value, StringComparison comparisonType) + => text.Contains(value, comparisonType); +#endif + } + + public class StringArguments + { + public int Size { get; } + + public string TestString1 { get; } + public string TestString2 { get; } + public string TestString3 { get; } + public string TestString4 { get; } + + public string Q1 { get; } + public string Q3 { get; } + + public override string ToString() => Size.ToString(); // this argument replaced an int argument called size + + public StringArguments(int size) + { + Size = size; + + PerfUtils utils = new PerfUtils(); + TestString1 = utils.CreateString(size); + TestString2 = utils.CreateString(size); + TestString3 = utils.CreateString(size); + TestString4 = utils.CreateString(size); + + Q1 = TestString1.Substring(0, TestString1.Length / 4); + Q3 = TestString1.Substring(TestString1.Length / 2, TestString1.Length / 4); + } + } +} \ No newline at end of file diff --git a/src/benchmarks/corefx/System.Runtime/Perf.StringBuilder.cs b/src/benchmarks/corefx/System.Runtime/Perf.StringBuilder.cs new file mode 100644 index 00000000000..7feb037d5f3 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.StringBuilder.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using System.Text; +using BenchmarkDotNet.Attributes; + +namespace System.Tests +{ + public class Perf_StringBuilder + { + private readonly string _string0 = ""; + private readonly string _string100 = new string(Enumerable.Repeat('a', 100).ToArray()); + private readonly string _string200 = new string(Enumerable.Repeat('a', 200).ToArray()); + private readonly string _string1000 = new string(Enumerable.Repeat('a', 1000).ToArray()); + private StringBuilder _bigStringBuilder; + + [Benchmark] + public void ctor() => new StringBuilder(); + + [Benchmark] + [Arguments(100)] + [Arguments(1000)] + public void ctor_string(int length) => new StringBuilder(length == 100 ? _string100 : _string1000); + + [Benchmark] + [Arguments(0)] + [Arguments(200)] + public void Append(int length) + { + string builtString = length == 0 ? _string0 : _string200; + StringBuilder empty = new StringBuilder(); + + for (int i = 0; i < 10000; i++) + empty.Append(builtString); // Appends a string of length "length" to an increasingly large StringBuilder + } + + public const int NUM_ITERS_CONCAT = 1000; + public const int NUM_ITERS_APPEND = 1000; + public const int NUM_ITERS_TOSTRING = 1000; + + public static string s1 = "12345"; + public static string s2 = "1234567890"; + public static string s3 = "1234567890abcde"; + public static string s4 = "1234567890abcdefghij"; + public static string s5 = "1234567890abcdefghijklmno"; + public static string s6 = "1234567890abcdefghijklmnopqrst"; + public static string s7 = "1234567890abcdefghijklmnopqrstuvwxy"; + public static string s8 = "1234567890abcdefghijklmnopqrstuvwxyzABCD"; + public static string s9 = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHI"; + public static string s10 = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN"; + + [Benchmark] + public string StringConcat() + { + string str = ""; + + for (int j = 0; j < NUM_ITERS_CONCAT; j++) + str += s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; + + return str; + } + + [Benchmark] + public StringBuilder StringBuilderAppend() + { + StringBuilder sb = new StringBuilder(); + + for (int j = 0; j < NUM_ITERS_APPEND; j++) + { + sb.Append(s1); + sb.Append(s2); + sb.Append(s3); + sb.Append(s4); + sb.Append(s5); + sb.Append(s6); + sb.Append(s7); + sb.Append(s8); + sb.Append(s9); + sb.Append(s10); + } + + return sb; + } + + [GlobalSetup(Target = nameof(StringBuilderToString))] + public void SetupStringBuilderToString() + { + StringBuilder sb = new StringBuilder(); + + for (int j = 0; j < NUM_ITERS_TOSTRING; j++) + { + sb.Append(s1); + sb.Append(s2); + sb.Append(s3); + sb.Append(s4); + sb.Append(s5); + sb.Append(s6); + sb.Append(s7); + sb.Append(s8); + sb.Append(s9); + sb.Append(s10); + } + + _bigStringBuilder = sb; + } + + [Benchmark] + public string StringBuilderToString() => _bigStringBuilder.ToString(); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.TimeSpan.cs b/src/benchmarks/corefx/System.Runtime/Perf.TimeSpan.cs new file mode 100644 index 00000000000..cecf1258c4f --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.TimeSpan.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_TimeSpan + { + [Benchmark] + public TimeSpan ctor_int_int_int() => new TimeSpan(7, 8, 10); + + [Benchmark] + public TimeSpan FromSeconds() => TimeSpan.FromSeconds(50); + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.Type.cs b/src/benchmarks/corefx/System.Runtime/Perf.Type.cs new file mode 100644 index 00000000000..e6fb6df7695 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.Type.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_Type + { + RuntimeTypeHandle TypeHandle = typeof(int).TypeHandle; + Type Type1 = typeof(int); + Type Type2 = typeof(string); + + [Benchmark] + public Type GetTypeFromHandle() => Type.GetTypeFromHandle(TypeHandle); + + [Benchmark] + public bool op_Equality() => Type1 == Type2; + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.UInt32.cs b/src/benchmarks/corefx/System.Runtime/Perf.UInt32.cs new file mode 100644 index 00000000000..964a8a371eb --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.UInt32.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_UInt32 + { + private char[] _destination = new char[uint.MaxValue.ToString().Length]; + + public IEnumerable StringValues => UInt32Values.Select(value => value.ToString()).ToArray(); + + public IEnumerable UInt32Values => new object[] + { + uint.MinValue, + (uint)12345, // same value used by other tests to compare the perf + uint.MaxValue, + }; + + [Benchmark] + [ArgumentsSource(nameof(UInt32Values))] + public string ToString(uint value) => value.ToString(); + +#if NETCOREAPP2_1 + [Benchmark] + [ArgumentsSource(nameof(UInt32Values))] + public bool TryFormat(uint value) => value.TryFormat(new Span(_destination), out _); + + [Benchmark] + [ArgumentsSource(nameof(StringValues))] + public void Parse(string value) => uint.Parse(value.AsSpan()); +#endif + } +} diff --git a/src/benchmarks/corefx/System.Runtime/Perf.UInt64.cs b/src/benchmarks/corefx/System.Runtime/Perf.UInt64.cs new file mode 100644 index 00000000000..e2d282d7bf1 --- /dev/null +++ b/src/benchmarks/corefx/System.Runtime/Perf.UInt64.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; +using Benchmarks; + +namespace System.Tests +{ + [BenchmarkCategory(Categories.CoreFX)] + public class Perf_UInt64 + { + private char[] _destination = new char[ulong.MaxValue.ToString().Length]; + + public IEnumerable StringValues => UInt64Values.Select(value => value.ToString()).ToArray(); + + public static object[] UInt64Values => new object[] + { + ulong.MinValue, + (ulong)12345, // same value used by other tests to compare the perf + ulong.MaxValue, + }; + + [Benchmark] + [ArgumentsSource(nameof(UInt64Values))] + public string ToString(ulong value) => value.ToString(); + +#if NETCOREAPP2_1 + [Benchmark] + [ArgumentsSource(nameof(UInt64Values))] + public bool TryFormat(ulong value) => value.TryFormat(new Span(_destination), out _); + + [Benchmark] + [ArgumentsSource(nameof(StringValues))] + public ulong Parse(string value) => ulong.Parse(value.AsSpan()); +#endif + } +}
#
See \nLiukin's routines
Misty, \nKerri survive scare
Biggest \nhits from Day 6