Skip to content

Commit d0368fc

Browse files
Merge branch 'main' into seo/70253-vertical-slice-architecture-aspnet-core
2 parents c72a7c6 + 73145d1 commit d0368fc

60 files changed

Lines changed: 925 additions & 264 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎collections-csharp/ConcurrentDictionary/ConcurrentDictionaryDemo/ConcurrentDictionaryDemo.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net7.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

‎collections-csharp/ConcurrentDictionary/ConcurrentDictionaryDemo/ContentionExample.cs‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,11 @@ public void RunWithEntryCheck()
4242

4343
private void ProcessingStep(int stepNumber)
4444
{
45-
int emptyHits = 0;
4645
for (int iteration = 0; iteration < MaxIterations; iteration++)
4746
{
4847
var entryKey = iteration % MaxStateEntries;
4948

50-
if (CheckStateIsEmpty())
51-
{
52-
emptyHits++;
53-
}
49+
CheckStateIsEmpty();
5450

5551
_sharedState.AddOrUpdate(
5652
entryKey,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public class NaiveExampleUnsized
2+
{
3+
public const int MaxIterations = 100;
4+
public const int MaxStateEntries = 10;
5+
public const int ProcessingSteps = 40;
6+
private Dictionary<int, int> _sharedState = new();
7+
8+
public void Run()
9+
{
10+
Parallel.ForEach(Enumerable.Range(0, ProcessingSteps), ProcessingStep);
11+
12+
PrintState();
13+
}
14+
15+
private void ProcessingStep(int stepNumber)
16+
{
17+
for (int iteration = 0; iteration < MaxIterations; iteration++)
18+
{
19+
var entryKey = iteration % MaxStateEntries;
20+
if (!_sharedState.TryGetValue(entryKey, out int entryValue))
21+
{
22+
entryValue = 0;
23+
}
24+
_sharedState[entryKey] = entryValue + 1;
25+
}
26+
}
27+
28+
private void PrintState()
29+
{
30+
foreach (var entry in _sharedState)
31+
{
32+
Console.WriteLine($"{entry.Key}\t{entry.Value}");
33+
}
34+
}
35+
}

‎collections-csharp/ConcurrentDictionary/ConcurrentDictionaryDemo/Program.cs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11

2+
try
3+
{
4+
new NaiveExampleUnsized().Run();
5+
}
6+
catch (AggregateException ex)
7+
{
8+
Console.WriteLine(ex);
9+
}
10+
11+
Console.WriteLine(new string('=', 20));
12+
213
new NaiveExample().Run();
314

415
Console.WriteLine(new string('=', 20));
@@ -15,9 +26,11 @@
1526

1627
Console.WriteLine(new string('=', 20));
1728

29+
Console.WriteLine("Running ContentionExample, this takes a few seconds...");
1830
new ContentionExample().Run();
1931

2032
Console.WriteLine(new string('=', 20));
2133

34+
Console.WriteLine("Running MemoryLeakExample, this takes a few seconds...");
2235
new MemoryLeakExample().Run();
2336

‎collections-csharp/ConcurrentDictionary/Tests/ContentionExampleIntegrationTest.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Tests
55
public class ContentionExampleIntegrationTest
66
{
77
private int expectedEntryValue = ContentionExample.ProcessingSteps * ContentionExample.MaxIterations / ContentionExample.MaxStateEntries;
8-
private ContentionExample sut = new();
8+
private ContentionExample sut;
99

1010
[SetUp]
1111
public void SetUp()
@@ -30,7 +30,7 @@ public void WhenRunSecondVariant_ThenAllStateEntriesHaveExpectedValue()
3030
}
3131

3232
[Test]
33-
public void WhenBothVariantsRun_ThenTheSecondVariantTakesMoreTime()
33+
public void WhenBothVariantsRun_ThenTheSecondVariantTakesMoreTime_Live()
3434
{
3535
ContentionExample firstVariant = new();
3636
ContentionExample secondVariant = new();

‎collections-csharp/ConcurrentDictionary/Tests/MemoryLeakExampleIntegrationTest.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public class MemoryLeakExampleIntegrationTest
44
{
55
private int expectedEntryValue = MemoryLeakExample.ProcessingSteps * MemoryLeakExample.MaxIterations / MemoryLeakExample.MaxStateEntries;
66

7-
private MemoryLeakExample sut = new();
7+
private MemoryLeakExample sut;
88

99
[SetUp]
1010
public void SetUp()

‎collections-csharp/ConcurrentDictionary/Tests/Tests.csproj‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net7.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77

88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
13-
<PackageReference Include="NUnit" Version="3.13.3" />
14-
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
15-
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
16-
<PackageReference Include="coverlet.collector" Version="3.1.2" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
13+
<PackageReference Include="NUnit" Version="4.6.1" />
14+
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
15+
<PackageReference Include="NUnit.Analyzers" Version="4.15.0" />
16+
<PackageReference Include="coverlet.collector" Version="10.0.1" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

‎collections-lists/ArrayListVsList/ArrayListVsList.sln‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,54 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArrayListVsList", "ArrayLis
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}"
11+
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1214
Debug|Any CPU = Debug|Any CPU
15+
Debug|x64 = Debug|x64
16+
Debug|x86 = Debug|x86
1317
Release|Any CPU = Release|Any CPU
18+
Release|x64 = Release|x64
19+
Release|x86 = Release|x86
1420
EndGlobalSection
1521
GlobalSection(ProjectConfigurationPlatforms) = postSolution
1622
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1723
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|x64.ActiveCfg = Debug|Any CPU
25+
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|x64.Build.0 = Debug|Any CPU
26+
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|x86.ActiveCfg = Debug|Any CPU
27+
{844DACC5-2552-4136-8EE4-EC215A721884}.Debug|x86.Build.0 = Debug|Any CPU
1828
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|Any CPU.ActiveCfg = Release|Any CPU
1929
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|x64.ActiveCfg = Release|Any CPU
31+
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|x64.Build.0 = Release|Any CPU
32+
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|x86.ActiveCfg = Release|Any CPU
33+
{844DACC5-2552-4136-8EE4-EC215A721884}.Release|x86.Build.0 = Release|Any CPU
2034
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2135
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|x64.ActiveCfg = Debug|Any CPU
37+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|x64.Build.0 = Debug|Any CPU
38+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|x86.ActiveCfg = Debug|Any CPU
39+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Debug|x86.Build.0 = Debug|Any CPU
2240
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|Any CPU.ActiveCfg = Release|Any CPU
2341
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|x64.ActiveCfg = Release|Any CPU
43+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|x64.Build.0 = Release|Any CPU
44+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|x86.ActiveCfg = Release|Any CPU
45+
{4B4BE163-4AD2-4848-AAD5-AB2C0A5F4F95}.Release|x86.Build.0 = Release|Any CPU
46+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|x64.ActiveCfg = Debug|Any CPU
49+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|x64.Build.0 = Debug|Any CPU
50+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|x86.ActiveCfg = Debug|Any CPU
51+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Debug|x86.Build.0 = Debug|Any CPU
52+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|Any CPU.ActiveCfg = Release|Any CPU
53+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|Any CPU.Build.0 = Release|Any CPU
54+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|x64.ActiveCfg = Release|Any CPU
55+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|x64.Build.0 = Release|Any CPU
56+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|x86.ActiveCfg = Release|Any CPU
57+
{FB7AABD4-ABF9-4D94-AD26-61A0DE6EA773}.Release|x86.Build.0 = Release|Any CPU
2458
EndGlobalSection
2559
GlobalSection(SolutionProperties) = preSolution
2660
HideSolutionNode = FALSE
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="BenchmarkDotNet" Version="0.15.4" />
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using System.Collections;
2+
using BenchmarkDotNet.Attributes;
3+
4+
namespace BoxingBench;
5+
6+
// Measures the one claim the article argues from mechanism: List is faster than ArrayList
7+
// because it does not box, so the effect is large for value types and small for reference types.
8+
// Both collections are created with the final capacity, so the only allocation difference left
9+
// is the boxing itself.
10+
[MemoryDiagnoser]
11+
public class BoxingBenchmark
12+
{
13+
private const int N = 1000;
14+
15+
private static readonly string[] Words = CreateWords();
16+
17+
private static string[] CreateWords()
18+
{
19+
var words = new string[N];
20+
for (var i = 0; i < N; i++)
21+
{
22+
words[i] = "item-" + i;
23+
}
24+
25+
return words;
26+
}
27+
28+
[Benchmark(Description = "ArrayList, 1000 int")]
29+
public int ArrayListOfInt()
30+
{
31+
var collection = new ArrayList(N);
32+
for (var i = 0; i < N; i++)
33+
{
34+
collection.Add(i);
35+
}
36+
37+
var sum = 0;
38+
foreach (var item in collection)
39+
{
40+
sum += (int)item!;
41+
}
42+
43+
return sum;
44+
}
45+
46+
[Benchmark(Description = "List, 1000 int")]
47+
public int ListOfInt()
48+
{
49+
var collection = new List<int>(N);
50+
for (var i = 0; i < N; i++)
51+
{
52+
collection.Add(i);
53+
}
54+
55+
var sum = 0;
56+
foreach (var item in collection)
57+
{
58+
sum += item;
59+
}
60+
61+
return sum;
62+
}
63+
64+
[Benchmark(Description = "ArrayList, 1000 string")]
65+
public int ArrayListOfString()
66+
{
67+
var collection = new ArrayList(N);
68+
for (var i = 0; i < N; i++)
69+
{
70+
collection.Add(Words[i]);
71+
}
72+
73+
var total = 0;
74+
foreach (var item in collection)
75+
{
76+
total += ((string)item!).Length;
77+
}
78+
79+
return total;
80+
}
81+
82+
[Benchmark(Description = "List, 1000 string")]
83+
public int ListOfString()
84+
{
85+
var collection = new List<string>(N);
86+
for (var i = 0; i < N; i++)
87+
{
88+
collection.Add(Words[i]);
89+
}
90+
91+
var total = 0;
92+
foreach (var item in collection)
93+
{
94+
total += item.Length;
95+
}
96+
97+
return total;
98+
}
99+
}

0 commit comments

Comments
 (0)