Skip to content

Commit

Permalink
Add CMAP a concurrent hashtable (#35)
Browse files Browse the repository at this point in the history
Add a concurrent hashmap, set targetframework to 9.0 (includes interlocked operations for byte)
  • Loading branch information
Wsm2110 committed Jun 5, 2024
1 parent 5b355b1 commit ac4bd1a
Show file tree
Hide file tree
Showing 174 changed files with 1,849 additions and 1,507 deletions.
40 changes: 20 additions & 20 deletions Faster.Map.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map.QuadMap.Tests",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map.RobinhoodMap.Tests", "unittests\Faster.Map.RobinhoodMap.Tests\Faster.Map.RobinhoodMap.Tests.csproj", "{C5F9A7E0-085D-4BA9-BD18-BDEDF987C35E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Faster.Map.Nuget.Tests", "unittests\Faster.Map.Nuget.Tests\Faster.Map.Nuget.Tests.csproj", "{9489C1F8-4BCC-407F-9B90-C4D2726F382E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map.CMap.Tests", "unittests\Faster.Map.CMap.Tests\Faster.Map.CMap.Tests.csproj", "{C917D320-324E-4696-BE76-18C967ABDAAD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map", "src\Faster.Map\Faster.Map.csproj", "{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map", "src\Faster.Map.csproj", "{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -71,22 +71,22 @@ Global
{C5F9A7E0-085D-4BA9-BD18-BDEDF987C35E}.Release|Any CPU.Build.0 = Release|Any CPU
{C5F9A7E0-085D-4BA9-BD18-BDEDF987C35E}.Release|x86.ActiveCfg = Release|Any CPU
{C5F9A7E0-085D-4BA9-BD18-BDEDF987C35E}.Release|x86.Build.0 = Release|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Debug|x86.ActiveCfg = Debug|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Debug|x86.Build.0 = Debug|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Release|Any CPU.Build.0 = Release|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Release|x86.ActiveCfg = Release|Any CPU
{9489C1F8-4BCC-407F-9B90-C4D2726F382E}.Release|x86.Build.0 = Release|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Debug|x86.ActiveCfg = Debug|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Debug|x86.Build.0 = Debug|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Release|Any CPU.Build.0 = Release|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Release|x86.ActiveCfg = Release|Any CPU
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5}.Release|x86.Build.0 = Release|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Debug|x86.ActiveCfg = Debug|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Debug|x86.Build.0 = Debug|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Release|Any CPU.Build.0 = Release|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Release|x86.ActiveCfg = Release|Any CPU
{C917D320-324E-4696-BE76-18C967ABDAAD}.Release|x86.Build.0 = Release|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Debug|x86.ActiveCfg = Debug|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Debug|x86.Build.0 = Debug|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Release|Any CPU.Build.0 = Release|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Release|x86.ActiveCfg = Release|Any CPU
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -97,8 +97,8 @@ Global
{398DC6D2-90BE-4A0F-9CFA-DD728260B379} = {D14F1A94-1E12-40B7-95AD-458306CAC233}
{023FBC3A-87FD-4789-9E3F-0DBE97BFE6D2} = {D14F1A94-1E12-40B7-95AD-458306CAC233}
{C5F9A7E0-085D-4BA9-BD18-BDEDF987C35E} = {D14F1A94-1E12-40B7-95AD-458306CAC233}
{9489C1F8-4BCC-407F-9B90-C4D2726F382E} = {D14F1A94-1E12-40B7-95AD-458306CAC233}
{6C8A8BB9-6DB6-4956-B203-BFF15E558AA5} = {21A59AB1-1ABE-404A-972E-21ECAE7DC24A}
{C917D320-324E-4696-BE76-18C967ABDAAD} = {D14F1A94-1E12-40B7-95AD-458306CAC233}
{205E2F61-AB6D-4BE2-B9C5-DAE5DED816B6} = {21A59AB1-1ABE-404A-972E-21ECAE7DC24A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B844430C-F4DE-4B2B-BD01-0E455BD01E41}
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/Faster.Map.Benchmark/Faster.Map.Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net9.0</TargetFrameworks>
<Platforms>AnyCPU</Platforms>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
Expand Down Expand Up @@ -39,7 +39,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Faster.Map\Faster.Map.csproj" />
<ProjectReference Include="..\..\src\Faster.Map.csproj" />
</ItemGroup>


Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Faster.Map.Benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<StringBenchmark>();
BenchmarkRunner.Run<GetBenchmark>();
}
}
}
85 changes: 79 additions & 6 deletions benchmarks/Faster.Map.Concurrent.Benchmark/AddBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,87 @@
using System.Collections.Concurrent;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Faster.Map.Concurrent;
using Faster.Map.DenseMap;
using Faster.Map.QuadMap;
using Faster.Map.RobinHoodMap;

namespace Faster.Map.Concurrent.Benchmark
{
[MarkdownExporterAttribute.GitHub]

[MemoryDiagnoser]
public class AddBenchmark
{
}
}
private CMap<uint, uint> _map;
private System.Collections.Concurrent.ConcurrentDictionary<int, int> _concurrentMap;
private NonBlocking.ConcurrentDictionary<uint, uint> _nonBlocking;

[Params(1000000)]
public uint Length { get; set; }
private uint[] keys;

private const int N = 1000000; // Adjust as needed for your scale

[Params(1, 8, 16, 32, 64, 128 /*, 256, 512*/)] // Example thread counts to test scalability
public int NumberOfThreads { get; set; }

[GlobalSetup]
public void Setup()
{
_map = new CMap<uint, uint>(2000000);
_nonBlocking = new NonBlocking.ConcurrentDictionary<uint, uint>(NumberOfThreads, 2000000);
_concurrentMap = new System.Collections.Concurrent.ConcurrentDictionary<int, int>(NumberOfThreads, 1000000);

var output = File.ReadAllText("Numbers.txt");
var splittedOutput = output.Split(',');

keys = new uint[Length];

for (var index = 0; index < Length; index++)
{
keys[index] = uint.Parse(splittedOutput[index]);
}
}

[IterationSetup]
public void Clean()
{
_map = new CMap<uint, uint>(2000000);
_nonBlocking = new NonBlocking.ConcurrentDictionary<uint, uint>(NumberOfThreads, 2000000);
_concurrentMap = new System.Collections.Concurrent.ConcurrentDictionary<int, int>(NumberOfThreads, 1000000);

}


[Benchmark]
public void NonBlocking()
{
Parallel.For(0, N, new ParallelOptions { MaxDegreeOfParallelism = NumberOfThreads }, i =>
{
var key = keys[i];
_nonBlocking.TryAdd(key, key);
});
}

[Benchmark]
public void CMap()
{
Parallel.For(0, N, new ParallelOptions { MaxDegreeOfParallelism = NumberOfThreads }, i =>
{
var key = keys[i];
_map.Emplace(key, key);
});
}

[Benchmark]
public void ConcurrentDictionary()
{
Parallel.For(0, N, new ParallelOptions { MaxDegreeOfParallelism = NumberOfThreads }, i =>
{
_concurrentMap.TryAdd(i, i);
});
}


}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net9.0</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="NonBlocking" Version="2.1.0" />
<None Remove="Numbers.txt" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Faster.Map\Faster.Map.csproj" />
<Content Include="Numbers.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<PackageReference Include="NonBlocking" Version="2.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Faster.Map.csproj" />
</ItemGroup>

</Project>
94 changes: 94 additions & 0 deletions benchmarks/Faster.Map.Concurrent.Benchmark/GetBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using BenchmarkDotNet.Attributes;
using Faster.Map.DenseMap;
using Faster.Map.QuadMap;
using Faster.Map.RobinHoodMap;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Faster.Map.Concurrent.Benchmark
{
public class GetBenchmark
{
CMap<uint, uint> _map = new CMap<uint, uint>();
NonBlocking.ConcurrentDictionary<uint, uint> _dic = new NonBlocking.ConcurrentDictionary<uint, uint>();
ConcurrentDictionary<uint, uint> _dic2;

[Params(1000000)]
public uint Length { get; set; }
private uint[] keys;


[Params(1, 8, 16, 32, 64, 128)] // Example thread counts to test scalability
public int NumberOfThreads { get; set; }


[GlobalSetup]
public void Setup()
{
_dic2 = new ConcurrentDictionary<uint, uint>(NumberOfThreads, 1);
var output = File.ReadAllText("Numbers.txt");
var splittedOutput = output.Split(',');

keys = new uint[Length];

for (var index = 0; index < Length; index++)
{
keys[index] = uint.Parse(splittedOutput[index]);
}

foreach (var key in keys)
{
_map.Emplace(key, key);
_dic.TryAdd(key, key);
_dic2.TryAdd(key, key);
}
}

[Benchmark]
public void ConcurrentDictionary()
{
Parallel.For(0, NumberOfThreads, i =>
{
for (int j = 0; j < Length; j++)
{
var key = keys[j];
_dic2.TryGetValue(key, out _);
}
});
}


[Benchmark]
public void NonBlocking()
{
Parallel.For(0, NumberOfThreads, i =>
{
for (int j = 0; j < Length; j++)
{
var key = keys[j];
_dic.TryGetValue(key, out _);
}
});
}

[Benchmark]
public void GetCmapBenchmark()
{
Parallel.For(0, NumberOfThreads, i =>
{
for (int j = 0; j < Length; j++)
{
var key = keys[j];
_map.Get(key, out _);
}
});
}
}
}
1 change: 1 addition & 0 deletions benchmarks/Faster.Map.Concurrent.Benchmark/Numbers.txt

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions benchmarks/Faster.Map.Concurrent.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running;

namespace Faster.Map.Concurrent.Benchmark
{
internal class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<AddBenchmark>();
{
BenchmarkRunner.Run<GetBenchmark>();
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit ac4bd1a

Please sign in to comment.