Skip to content

Commit bcf9863

Browse files
Add PriorityQueue benchmarks (#1665)
1 parent 6e941f7 commit bcf9863

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

src/benchmarks/micro/MicroBenchmarks.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@
109109
<Compile Remove="libraries\System.Formats.Cbor\*.cs" />
110110
</ItemGroup>
111111

112+
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' Or ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(_TargetFrameworkVersionWithoutV)' &lt; '6.0')">
113+
<Compile Remove="libraries\System.Collections\PriorityQueue\Perf_PriorityQueue.cs" />
114+
</ItemGroup>
115+
112116
<ItemGroup>
113117
<!-- Workaround https://github.com/dotnet/project-system/issues/935 -->
114118
<None Include="**/*.cs" />
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Linq;
7+
using System.Collections.Generic;
8+
using BenchmarkDotNet.Attributes;
9+
using BenchmarkDotNet.Extensions;
10+
using MicroBenchmarks;
11+
12+
namespace System.Collections.Tests
13+
{
14+
[BenchmarkCategory(Categories.Libraries, Categories.Collections, Categories.GenericCollections)]
15+
[GenericTypeArguments(typeof(int), typeof(int))]
16+
[GenericTypeArguments(typeof(string), typeof(string))]
17+
[GenericTypeArguments(typeof(Guid), typeof(Guid))]
18+
public class Perf_PriorityQueue<TElement, TPriority>
19+
{
20+
[Params(10, 100, 1000)]
21+
public int Size;
22+
23+
private (TElement Element, TPriority Priority)[] _items;
24+
private PriorityQueue<TElement, TPriority> _priorityQueue;
25+
private PriorityQueue<TElement, TPriority> _prePopulatedPriorityQueue;
26+
27+
[GlobalSetup]
28+
public void Setup()
29+
{
30+
_items = ValuesGenerator.Array<TElement>(Size).Zip(ValuesGenerator.Array<TPriority>(Size)).ToArray();
31+
_priorityQueue = new PriorityQueue<TElement, TPriority>(initialCapacity: Size);
32+
_prePopulatedPriorityQueue = new PriorityQueue<TElement, TPriority>(_items);
33+
}
34+
35+
[Benchmark]
36+
public void HeapSort()
37+
{
38+
var queue = _priorityQueue;
39+
queue.EnqueueRange(_items);
40+
41+
while (queue.Count > 0)
42+
{
43+
queue.Dequeue();
44+
}
45+
}
46+
47+
[Benchmark]
48+
public void Enumerate()
49+
{
50+
foreach (var _ in _prePopulatedPriorityQueue.UnorderedItems)
51+
{
52+
53+
}
54+
}
55+
56+
[Benchmark]
57+
public void Dequeue_And_Enqueue()
58+
{
59+
// benchmarks dequeue and enqueue operations
60+
// for heaps of fixed size.
61+
62+
var queue = _priorityQueue;
63+
var items = _items;
64+
65+
// populate the heap: incorporated in the
66+
// benchmark to achieve determinism.
67+
foreach ((TElement element, TPriority priority) in items)
68+
{
69+
queue.Enqueue(element, priority);
70+
}
71+
72+
foreach ((TElement element, TPriority priority) in items)
73+
{
74+
queue.Dequeue();
75+
queue.Enqueue(element, priority);
76+
}
77+
78+
// Drain the heap
79+
while (queue.Count > 0)
80+
{
81+
queue.Dequeue();
82+
}
83+
}
84+
85+
[Benchmark]
86+
public void K_Max_Elements()
87+
{
88+
const int k = 5;
89+
var queue = _priorityQueue;
90+
var items = _items;
91+
92+
for (int i = 0; i < k; i++)
93+
{
94+
(TElement element, TPriority priority) = items[i];
95+
queue.Enqueue(element, priority);
96+
}
97+
98+
for (int i = k; i < Size; i++)
99+
{
100+
(TElement element, TPriority priority) = items[i];
101+
queue.EnqueueDequeue(element, priority);
102+
}
103+
104+
for (int i = 0; i < k; i++)
105+
{
106+
queue.Dequeue();
107+
}
108+
}
109+
}
110+
}

src/harness/BenchmarkDotNet.Extensions/ValuesGenerator.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ private static T GenerateValue<T>(Random random)
112112
return (T)(object)(random.NextDouble() > 0.5);
113113
if (typeof(T) == typeof(string))
114114
return (T)(object)GenerateRandomString(random, 1, 50);
115+
if (typeof(T) == typeof(Guid))
116+
return (T)(object)GenerateRandomGuid(random);
115117

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

136138
return builder.ToString();
137139
}
140+
141+
private static Guid GenerateRandomGuid(Random random)
142+
{
143+
byte[] bytes = new byte[16];
144+
random.NextBytes(bytes);
145+
return new Guid(bytes);
146+
}
138147
}
139148
}

0 commit comments

Comments
 (0)