Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Runtime #112

Merged
merged 31 commits into from
Aug 15, 2018
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e2fe011
copy
adamsitnik Aug 10, 2018
c66a689
port
adamsitnik Aug 10, 2018
b91cb00
fix typo: this method accept string, not long values..
adamsitnik Aug 11, 2018
c3f68f7
update to BDN which handles double special values as arguments correc…
adamsitnik Aug 11, 2018
2828265
remove duplicated benchmark ArrayCreate (CtorGivenSize.Array)
adamsitnik Aug 13, 2018
f1c8705
remove duplicated benchmark ArrayCopy (System.Collections.CopyTo.Array)
adamsitnik Aug 13, 2018
ad3831c
remove duplicated benchmark ArrayAssign(System.Collections.IndexerSet…
adamsitnik Aug 13, 2018
6c75bd2
remove duplicated benchmark ArrayRetrieve (System.Collections.Iterate…
adamsitnik Aug 13, 2018
c20cb12
remove duplicated benchmark ArrayCopy1D (System.Collections.CopyTo.Ar…
adamsitnik Aug 13, 2018
25e960c
port remaining Array benchmarks
adamsitnik Aug 13, 2018
8d1c00f
port String benchmarks
adamsitnik Aug 13, 2018
71bbbd3
remove duplicated benchmarks which check same thing what other benchm…
adamsitnik Aug 13, 2018
2b91382
port remaining string benchmarks
adamsitnik Aug 13, 2018
be83a43
fixing the BDN compile errors
adamsitnik Aug 13, 2018
1fd7ae3
dont forget to initialize all the fields.. (my bad)
adamsitnik Aug 13, 2018
ebfc1a1
make sure the result of array.GetValue is consumed and not optimized …
adamsitnik Aug 14, 2018
5c566b9
reduce the number of permutations for int, uint, long, ulong and doub…
adamsitnik Aug 14, 2018
0f6d66a
refactor string benchmarks into multiple files to make it slightly mo…
adamsitnik Aug 14, 2018
9220cd5
reduce the number of ToLower/ToUpper test cases from 11 to 3, -32 ben…
adamsitnik Aug 14, 2018
ba02aaf
reduce the number of Equals test cases from 9 to 1, -16 benchmarks
adamsitnik Aug 14, 2018
3e20ced
reduce the number of Compare test cases, use Arguments instead of Arg…
adamsitnik Aug 14, 2018
e93ea26
reduce the number of Format benchmark cases, -11 benchmarks
adamsitnik Aug 14, 2018
30eb020
reduce the number of Trim benchmark cases, MINUS THREE HUNDRED EIGHT …
adamsitnik Aug 14, 2018
7538f6c
implement a Validator that will prevent the users from adding TOO MAN…
adamsitnik Aug 14, 2018
fa30bbe
reduce the number of Replace benchmark cases and some better ones, MI…
adamsitnik Aug 14, 2018
605d483
reduce the number of Split benchmark cases and some better ones, MINU…
adamsitnik Aug 14, 2018
4ff0189
remove more test cases..
adamsitnik Aug 14, 2018
eb0344f
rewrite the Contains benchmark
adamsitnik Aug 14, 2018
ea5acb5
merge all String benchmarks into one file - after removing the test c…
adamsitnik Aug 14, 2018
522d760
cleanup
adamsitnik Aug 14, 2018
79a363b
added string interpolation to be able to compare with String.Format
adamsitnik Aug 15, 2018
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
3 changes: 2 additions & 1 deletion src/benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<None Remove="img\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.14.683" />
<PackageReference Include="BenchmarkDotNet" Version="0.11.0.723" />
<PackageReference Include="CommandLineParser" Version="2.2.1" />
<PackageReference Include="Jil" Version="2.15.4" />
<PackageReference Include="MessagePack" Version="1.7.3.4" />
Expand Down Expand Up @@ -53,6 +53,7 @@
<Compile Remove="corefx\System.Net.Sockets\Perf.Socket.SendReceive.cs" />
<Compile Remove="corefx\System.Numerics.Vectors\GenericVectorFromSpanConstructorTests.cs" />
<Compile Remove="corefx\System.IO.Compression\Brotli.cs" />
<Compile Remove="corefx\System.Runtime\Perf.HashCode.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="$(NuGetPackageRoot)\system.text.regularexpressions.testdata\1.0.2\content\regexredux\*.*">
Expand Down
29 changes: 29 additions & 0 deletions src/benchmarks/Harness/TooManyTestCasesValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

using System.Linq;
using BenchmarkDotNet.Validators;

namespace Benchmarks
{
/// <summary>
/// we need to tell our users that having more than 20 test cases per benchmark is a VERY BAD idea
/// </summary>
public class TooManyTestCasesValidator : IValidator
{
private const int Limit = 16;

public static readonly IValidator FailOnError = new TooManyTestCasesValidator();

public bool TreatsWarningsAsErrors => true;

public IEnumerable<ValidationError> 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()));
}
}
}
2 changes: 2 additions & 0 deletions src/benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
273 changes: 273 additions & 0 deletions src/benchmarks/corefx/System.Runtime/Perf.Array.cs
Original file line number Diff line number Diff line change
@@ -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<byte>(ref _byteArrays[i], NewSize);
}
}
}
19 changes: 19 additions & 0 deletions src/benchmarks/corefx/System.Runtime/Perf.Boolean.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
31 changes: 31 additions & 0 deletions src/benchmarks/corefx/System.Runtime/Perf.Char.cs
Original file line number Diff line number Diff line change
@@ -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<object[]> 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);
}
}
Loading