Skip to content

Commit de983a9

Browse files
committed
Added Benchmark and bumped version
1 parent 72473ab commit de983a9

File tree

5 files changed

+143
-1
lines changed

5 files changed

+143
-1
lines changed

Benchmark/Benchmark.csproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<ProjectReference Include="..\Lockless-Queue\Lockless-Queue.csproj" />
14+
</ItemGroup>
15+
16+
</Project>

Benchmark/Program.cs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Running;
3+
using LocklessQueues;
4+
using System;
5+
using System.Collections.Generic;
6+
using SysConcurrentQueue = System.Collections.Concurrent.ConcurrentQueue<long>;
7+
8+
namespace Benchmark
9+
{
10+
class Program
11+
{
12+
static void Main(string[] args)
13+
{
14+
BenchmarkRunner.Run<Benchmarks>();
15+
Console.ReadLine();
16+
}
17+
}
18+
19+
[MemoryDiagnoser]
20+
public class Benchmarks
21+
{
22+
const int COUNT = 128;
23+
24+
readonly ConcurrentQueue<long> _concurrentQueue;
25+
readonly SysConcurrentQueue _systemConcurrentQueue;
26+
readonly MPSCQueue<long> _mpscQueue;
27+
readonly SPSCQueue<long> _spscQueue;
28+
readonly Queue<long> _queue;
29+
30+
public Benchmarks()
31+
{
32+
_concurrentQueue = new ConcurrentQueue<long>(COUNT, true);
33+
_systemConcurrentQueue = new SysConcurrentQueue();
34+
_mpscQueue = new MPSCQueue<long>(COUNT);
35+
_spscQueue = new SPSCQueue<long>(COUNT);
36+
_queue = new Queue<long>(COUNT);
37+
}
38+
39+
[Benchmark]
40+
public void ConcurrentQueue()
41+
{
42+
// ADD values
43+
for (int i = 0; i < COUNT; i++)
44+
_concurrentQueue.TryEnqueue(i);
45+
46+
for (int i = 0; i < COUNT; i++)
47+
_concurrentQueue.TryDequeue(out long result);
48+
49+
_concurrentQueue.Clear();
50+
}
51+
52+
[Benchmark]
53+
public void SysConcurrentQueue()
54+
{
55+
// ADD values
56+
for (int i = 0; i < COUNT; i++)
57+
_systemConcurrentQueue.Enqueue(i);
58+
59+
for (int i = 0; i < COUNT; i++)
60+
_systemConcurrentQueue.TryDequeue(out long result);
61+
62+
_systemConcurrentQueue.Clear();
63+
}
64+
65+
[Benchmark]
66+
public void MPSCQueue()
67+
{
68+
// ADD values
69+
for (int i = 0; i < COUNT; i++)
70+
_mpscQueue.TryEnqueue(i);
71+
72+
for (int i = 0; i < COUNT; i++)
73+
_mpscQueue.TryDequeue(out long result);
74+
75+
_mpscQueue.Clear();
76+
}
77+
78+
[Benchmark]
79+
public void SPSCQueue()
80+
{
81+
// ADD values
82+
for (int i = 0; i < COUNT; i++)
83+
_spscQueue.TryEnqueue(i);
84+
85+
for (int i = 0; i < COUNT; i++)
86+
_spscQueue.TryDequeue(out long result);
87+
88+
_spscQueue.Clear();
89+
}
90+
91+
[Benchmark]
92+
public void Queue()
93+
{
94+
// ADD values
95+
for (int i = 0; i < COUNT; i++)
96+
_queue.Enqueue(i);
97+
98+
for (int i = 0; i < COUNT; i++)
99+
_queue.TryDequeue(out long result);
100+
101+
_queue.Clear();
102+
}
103+
}
104+
}

Lockless-Queue.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ VisualStudioVersion = 15.0.28307.1300
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lockless-Queue", "Lockless-Queue\Lockless-Queue.csproj", "{E40F468B-84F2-4D29-8F8F-425EA84D44FA}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocklessQueuesTests", "LocklessQueuesTests\LocklessQueuesTests.csproj", "{051B182C-7FC4-4F19-96AE-17C706002836}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LocklessQueuesTests", "LocklessQueuesTests\LocklessQueuesTests.csproj", "{051B182C-7FC4-4F19-96AE-17C706002836}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark\Benchmark.csproj", "{749C39AD-73C0-43F3-AF8F-D39348A552D0}"
911
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
2123
{051B182C-7FC4-4F19-96AE-17C706002836}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{051B182C-7FC4-4F19-96AE-17C706002836}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{051B182C-7FC4-4F19-96AE-17C706002836}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{749C39AD-73C0-43F3-AF8F-D39348A552D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{749C39AD-73C0-43F3-AF8F-D39348A552D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{749C39AD-73C0-43F3-AF8F-D39348A552D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{749C39AD-73C0-43F3-AF8F-D39348A552D0}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE

Lockless-Queue/Lockless-Queue.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The Concurrent Queue implementation is a copy of the .Net 5.0 implementation wit
1818
<Copyright>Copyright (c) 2021 Dennis Corvers</Copyright>
1919
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
2020
<PackageLicenseUrl>https://github.com/DennisCorvers/Lockless-Queue/blob/master/LICENSE</PackageLicenseUrl>
21+
<Version>1.0.1</Version>
22+
<PackageTags>lockless lockfree concurrent queue CAS</PackageTags>
2123
</PropertyGroup>
2224

2325
</Project>

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,17 @@ The following queue implementations are present:
77
- Concurrent Queue (Multi Producer, Multi Consumer).
88

99
The Concurrent Queue implementation is a **copy** of the .Net 5.0 implementation with the added option for a fixed-size queue. This queue is lockless if/when it is instantiated as a fixed-size queue.
10+
11+
## Benchmarks
12+
13+
SysConcurrentQueue and Queue are the built-in .Net types. Where possible, a fixed-size queue has been used.
14+
15+
The following Benchmarks execute Enqueueing 128 items, Dequeueing 128 items and finally clearing the Queue. The same methods are used for each queue where available. All Queue benchmarks are run in a single-threaded environment to demonstrate the "raw" throughput of each queue.
16+
17+
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
18+
|------------------- |-----------:|---------:|---------:|-------:|-------:|------:|----------:|
19+
| ConcurrentQueue | 2,507.0 ns | 6.52 ns | 6.10 ns | - | - | - | - |
20+
| SysConcurrentQueue | 2,943.2 ns | 23.93 ns | 21.21 ns | 0.7782 | 0.0153 | - | 4928 B |
21+
| MPSCQueue | 1,655.7 ns | 1.30 ns | 1.22 ns | - | - | - | - |
22+
| SPSCQueue | 512.7 ns | 3.13 ns | 2.93 ns | - | - | - | - |
23+
| Queue | 588.7 ns | 1.75 ns | 1.63 ns | - | - | - | - |

0 commit comments

Comments
 (0)