Skip to content

Add PriorityQueue benchmarks #1665

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

Merged
merged 7 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/benchmarks/micro/MicroBenchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@
<Compile Remove="libraries\System.Formats.Cbor\*.cs" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' Or ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(_TargetFrameworkVersionWithoutV)' &lt; '6.0')">
<Compile Remove="libraries\System.Collections\PriorityQueue\Perf_PriorityQueue.cs" />
</ItemGroup>

<ItemGroup>
<!-- Workaround https://github.com/dotnet/project-system/issues/935 -->
<None Include="**/*.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// 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.Linq;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;

namespace System.Collections.Tests
{
[BenchmarkCategory(Categories.Libraries, Categories.Collections, Categories.GenericCollections)]
[GenericTypeArguments(typeof(int), typeof(int))]
[GenericTypeArguments(typeof(string), typeof(string))]
[GenericTypeArguments(typeof(Guid), typeof(Guid))]
public class Perf_PriorityQueue<TElement, TPriority>
{
[Params(10, 100, 1000)]
public int Size;

private (TElement Element, TPriority Priority)[] _items;
private PriorityQueue<TElement, TPriority> _priorityQueue;
private PriorityQueue<TElement, TPriority> _prePopulatedPriorityQueue;

[GlobalSetup]
public void Setup()
{
_items = ValuesGenerator.Array<TElement>(Size).Zip(ValuesGenerator.Array<TPriority>(Size)).ToArray();
_priorityQueue = new PriorityQueue<TElement, TPriority>(initialCapacity: Size);
_prePopulatedPriorityQueue = new PriorityQueue<TElement, TPriority>(_items);
}

[Benchmark]
public void HeapSort()
{
var queue = _priorityQueue;
queue.EnqueueRange(_items);

while (queue.Count > 0)
{
queue.Dequeue();
}
}

[Benchmark]
public void Enumerate()
{
foreach (var _ in _prePopulatedPriorityQueue.UnorderedItems)
{

}
}

[Benchmark]
public void Dequeue_And_Enqueue()
{
// benchmarks dequeue and enqueue operations
// for heaps of fixed size.

var queue = _priorityQueue;
var items = _items;

// populate the heap: incorporated in the
// benchmark to achieve determinism.
foreach ((TElement element, TPriority priority) in items)
{
queue.Enqueue(element, priority);
}

foreach ((TElement element, TPriority priority) in items)
{
queue.Dequeue();
queue.Enqueue(element, priority);
}

// Drain the heap
while (queue.Count > 0)
{
queue.Dequeue();
}
}

[Benchmark]
public void K_Max_Elements()
{
const int k = 5;
var queue = _priorityQueue;
var items = _items;

for (int i = 0; i < k; i++)
{
(TElement element, TPriority priority) = items[i];
queue.Enqueue(element, priority);
}

for (int i = k; i < Size; i++)
{
(TElement element, TPriority priority) = items[i];
queue.EnqueueDequeue(element, priority);
}

for (int i = 0; i < k; i++)
{
queue.Dequeue();
}
}
}
}
9 changes: 9 additions & 0 deletions src/harness/BenchmarkDotNet.Extensions/ValuesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ private static T GenerateValue<T>(Random random)
return (T)(object)(random.NextDouble() > 0.5);
if (typeof(T) == typeof(string))
return (T)(object)GenerateRandomString(random, 1, 50);
if (typeof(T) == typeof(Guid))
return (T)(object)GenerateRandomGuid(random);

throw new NotImplementedException($"{typeof(T).Name} is not implemented");
}
Expand All @@ -135,5 +137,12 @@ private static string GenerateRandomString(Random random, int minLength, int max

return builder.ToString();
}

private static Guid GenerateRandomGuid(Random random)
{
byte[] bytes = new byte[16];
random.NextBytes(bytes);
return new Guid(bytes);
}
}
}