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.Memory #94

Merged
merged 22 commits into from
Sep 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6a78d76
Span, ReadOnlySpan, Memory, ReadOnlyMemory constructors benchmarks
adamsitnik Jul 19, 2018
efe65a3
Merge remote-tracking branch 'upstream/master' into memory
adamsitnik Jul 20, 2018
e1d682b
Span indexer benchmarks
adamsitnik Jul 20, 2018
7f39dad
move Clear Span and Array benchmarks to Clear benchmarks of all colle…
adamsitnik Jul 20, 2018
0d77294
move CopyTo Span and Array benchmarks to CopyTo benchmarks of all col…
adamsitnik Jul 20, 2018
5ecd3ee
make sure we always have the same random data to compare apples to ap…
adamsitnik Jul 20, 2018
a84b4b3
cleanup Sorting benchmarks
adamsitnik Jul 20, 2018
b70fd3b
reorganize Span benchmarks
adamsitnik Jul 20, 2018
b7619ef
add For loop benchmark for ReadOnlySpan
adamsitnik Jul 20, 2018
b8f2237
we can't generate an array of more than 255 unique bytes so for some …
adamsitnik Jul 20, 2018
df97862
port MemoryMarshal benchmark from CoreFX
adamsitnik Jul 20, 2018
e0b2e18
port more Span benchmarks
adamsitnik Jul 20, 2018
6fd10e1
port more ROS Benchmarks
adamsitnik Jul 20, 2018
9ba417e
add benchmarks for creating Span from Memory
adamsitnik Jul 31, 2018
a822c76
implement Slice benchmarks
adamsitnik Jul 31, 2018
3a4f675
implement foreach benchmarks for Span and ROS
adamsitnik Jul 31, 2018
b67628a
add missing license header
adamsitnik Aug 1, 2018
1d8a584
add CopyTo benchmarks for ROS and Memory
adamsitnik Aug 1, 2018
374a6a2
and Memory.Pin benchmarks
adamsitnik Aug 1, 2018
723dd6c
simplify the slicing benchmark code
adamsitnik Aug 1, 2018
24ecd7f
add memory.ToArray benchmarks
adamsitnik Aug 1, 2018
68587cd
add GetPinnableReference benchmarks
adamsitnik Aug 1, 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
2 changes: 2 additions & 0 deletions src/benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="img\**" />
<Compile Remove="Tests\**" />
<EmbeddedResource Remove="img\**" />
<None Remove="img\**" />
<None Remove="Tests\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.14.683" />
Expand Down
8 changes: 7 additions & 1 deletion src/benchmarks/Benchmarks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2011
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks.csproj", "{D99F63AE-3154-4F13-9424-FA5F9D032D1D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks.csproj", "{D99F63AE-3154-4F13-9424-FA5F9D032D1D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{A40E51E2-99EB-4F64-ADCC-94FEA3FF1399}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +17,10 @@ Global
{D99F63AE-3154-4F13-9424-FA5F9D032D1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D99F63AE-3154-4F13-9424-FA5F9D032D1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D99F63AE-3154-4F13-9424-FA5F9D032D1D}.Release|Any CPU.Build.0 = Release|Any CPU
{A40E51E2-99EB-4F64-ADCC-94FEA3FF1399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A40E51E2-99EB-4F64-ADCC-94FEA3FF1399}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A40E51E2-99EB-4F64-ADCC-94FEA3FF1399}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A40E51E2-99EB-4F64-ADCC-94FEA3FF1399}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
15 changes: 15 additions & 0 deletions src/benchmarks/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Benchmarks.csproj" />
</ItemGroup>
</Project>
49 changes: 49 additions & 0 deletions src/benchmarks/Tests/UniqueValuesGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Linq;
using Benchmarks;
using Xunit;

namespace Tests
{
public class UniqueValuesGeneratorTests
{
[Fact]
public void UnsupportedTypesThrow()
=> Assert.Throws<NotImplementedException>(() => ValuesGenerator.ArrayOfUniqueValues<UniqueValuesGeneratorTests>(1));

[Fact]
public void GeneratedArraysContainOnlyUniqueValues()
{
AssertGeneratedArraysContainOnlyUniqueValues<int>(1024);
AssertGeneratedArraysContainOnlyUniqueValues<string>(1024);
}

private void AssertGeneratedArraysContainOnlyUniqueValues<T>(int size)
{
var generatedArray = ValuesGenerator.ArrayOfUniqueValues<T>(size);

var distinct = generatedArray.Distinct().ToArray();

Assert.Equal(distinct, generatedArray);
}

[Fact]
public void GeneratedArraysContainAlwaysSameValues()
{
AssertGeneratedArraysContainAlwaysSameValues<int>(1024);
AssertGeneratedArraysContainAlwaysSameValues<string>(1024);
}

private void AssertGeneratedArraysContainAlwaysSameValues<T>(int size)
{
var generatedArray = ValuesGenerator.ArrayOfUniqueValues<T>(size);

for (int i = 0; i < 10; i++)
{
var anotherGeneratedArray = ValuesGenerator.ArrayOfUniqueValues<T>(size);

Assert.Equal(generatedArray, anotherGeneratedArray);
}
}
}
}
94 changes: 94 additions & 0 deletions src/benchmarks/ValuesGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Benchmarks
{
public static class ValuesGenerator
{
private const int Seed = 12345; // we always use the same seed to have repeatable results!

public static T GetNonDefaultValue<T>() => ArrayOfUniqueValues<T>(2).First(value => !value.Equals(default));

public static T[] ArrayOfUniqueValues<T>(int count)
{
var random = new Random(Seed);

var uniqueValues = new HashSet<T>();

while (uniqueValues.Count != count)
{
T value = GenerateValue<T>(random);

if (!uniqueValues.Contains(value))
uniqueValues.Add(value);
}

return uniqueValues.ToArray();
}

public static T[] Array<T>(int count)
{
var random = new Random(Seed);

var result = new T[count];

if (typeof(T) == typeof(byte))
{
random.NextBytes((byte[])(object)result);
}
else
{
for (int i = 0; i < result.Length; i++)
{
result[i] = GenerateValue<T>(random);
}
}

return result;
}

public static Dictionary<TKey, TValue> Dictionary<TKey, TValue>(int count)
{
var random = new Random(Seed);

var dictionary = new Dictionary<TKey, TValue>();

while (dictionary.Count != count)
{
TKey key = GenerateValue<TKey>(random);

if (!dictionary.ContainsKey(key))
dictionary.Add(key, GenerateValue<TValue>(random));
}

return dictionary;
}

private static T GenerateValue<T>(Random random)
{
if (typeof(T) == typeof(char))
return (T)(object)(char)random.Next(char.MinValue, char.MaxValue);
if (typeof(T) == typeof(int))
return (T)(object)random.Next();
if (typeof(T) == typeof(double))
return (T)(object)random.NextDouble();
if (typeof(T) == typeof(string))
return (T) (object) GenerateRandomString(random, 1, 50);

throw new NotImplementedException($"{typeof(T).Name} is not implemented");
}

private static string GenerateRandomString(Random random, int minLength, int maxLength)
{
var length = random.Next(minLength, maxLength);

var builder = new StringBuilder(length);
for (int i = 0; i < length; i++)
builder.Append((char) random.Next(char.MinValue, char.MaxValue));

return builder.ToString();
}
}
}
176 changes: 176 additions & 0 deletions src/benchmarks/coreclr/Span/Sorting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// 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;
using System.Collections;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using Benchmarks;

namespace Span
{
[BenchmarkCategory(Categories.CoreCLR)]
[InvocationCount(InvocationsPerIteration)]
public class Sorting
{
private const int InvocationsPerIteration = 1000;

[Params(Utils.DefaultCollectionSize)]
public int Size;

private int _iterationIndex = 0;
private int[] _values;

private int[][] _arrays;

[GlobalSetup]
public void Setup() => _values = ValuesGenerator.ArrayOfUniqueValues<int>(Size);

[IterationSetup]
public void SetupIteration() => Utils.FillArrays(ref _arrays, InvocationsPerIteration, _values);

[IterationCleanup]
public void CleanupIteration() => _iterationIndex = 0; // after every iteration end we set the index to 0

[BenchmarkCategory(Categories.Span)]
[Benchmark]
public void QuickSortSpan() => TestQuickSortSpan(new Span<int>(_arrays[_iterationIndex++]));

[BenchmarkCategory(Categories.Span)]
[Benchmark]
public void BubbleSortSpan() => TestBubbleSortSpan(new Span<int>(_arrays[_iterationIndex++]));

[Benchmark]
public void QuickSortArray() => TestQuickSortArray(_arrays[_iterationIndex++], 0, Size);

[Benchmark]
public void BubbleSortArray() => TestBubbleSortArray(_arrays[_iterationIndex++]);

[MethodImpl(MethodImplOptions.NoInlining)]
static void TestQuickSortArray(int[] data, int lo, int hi)
{
if (lo >= hi)
{
return;
}

int i, j;
int pivot, temp;
for (i = lo, j = hi, pivot = data[hi]; i < j;)
{
while (i < j && data[i] <= pivot)
{
++i;
}
while (j > i && data[j] >= pivot)
{
--j;
}
if (i < j)
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
if (i != hi)
{
temp = data[i];
data[i] = pivot;
data[hi] = temp;
}

TestQuickSortArray(data, lo, i - 1);
TestQuickSortArray(data, i + 1, hi);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void TestQuickSortSpan(Span<int> data)
{
if (data.Length <= 1)
{
return;
}

int lo = 0;
int hi = data.Length - 1;
int i, j;
int pivot, temp;
for (i = lo, j = hi, pivot = data[hi]; i < j;)
{
while (i < j && data[i] <= pivot)
{
++i;
}
while (j > i && data[j] >= pivot)
{
--j;
}
if (i < j)
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
if (i != hi)
{
temp = data[i];
data[i] = pivot;
data[hi] = temp;
}

TestQuickSortSpan(data.Slice(0, i));
TestQuickSortSpan(data.Slice(i + 1));
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void TestBubbleSortArray(int[] data)
{
bool swap;
int temp;
int n = data.Length - 1;
do
{
swap = false;
for (int i = 0; i < n; i++)
{
if (data[i] > data[i + 1])
{
temp = data[i];
data[i] = data[i + 1];
data[i + 1] = temp;
swap = true;
}
}
--n;
}
while (swap);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void TestBubbleSortSpan(Span<int> span)
{
bool swap;
int temp;
int n = span.Length - 1;
do
{
swap = false;
for (int i = 0; i < n; i++)
{
if (span[i] > span[i + 1])
{
temp = span[i];
span[i] = span[i + 1];
span[i + 1] = temp;
swap = true;
}
}
--n;
}
while (swap);
}
}
}
Loading