== Resources

=== Documentation

* https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2.getoradd[ConcurrentDictionary<TKey,TValue>.GetOrAdd]
* https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2.addorupdate[ConcurrentDictionary<TKey,TValue>.AddOrUpdate]


=== Benchmarks

[options="header"]
|===
| Method  | Runtime              | Mean      | Standard Deviation | Allocated
| Capture |             .NET 7.0 |  68.52 ms | 4.450 ms | 88000063 B
|  Lambda |             .NET 7.0 |  39.29 ms | 3.712 ms |       50 B
| Capture | .NET Framework 4.6.2 |  74.58 ms | 5.199 ms | 88259787 B
|  Lambda | .NET Framework 4.6.2 |  42.03 ms | 2.752 ms |          -
|===

==== Glossary

* https://en.wikipedia.org/wiki/Arithmetic_mean[Mean]
* https://en.wikipedia.org/wiki/Standard_deviation[Standard Deviation]
* https://en.wikipedia.org/wiki/Memory_management[Allocated]

The results were generated by running the following snippet with https://github.com/dotnet/BenchmarkDotNet[BenchmarkDotNet]:

[source,csharp]
----
private ConcurrentDictionary<int, string> dict;
private List<int> data;

[Params(1_000_000)]
public int N { get; set; }

[GlobalSetup]
public void Setup()
{
    dict = new ConcurrentDictionary<int, string>();
    data = Enumerable.Range(0, N).OrderBy(_ => Guid.NewGuid()).ToList();
}

[Benchmark(baseline=true)]
public void Capture()
{
    foreach (var guid in data)
    {
        dict.GetOrAdd(guid, _ => $"{guid}"); // "guid" is captured
    }
}

[Benchmark]
public void Lambda()
{
    foreach (var guid in data)
    {
        dict.GetOrAdd(guid, x => $"{x}"); // no capture
    }
}

----

Hardware configuration:
[source]
----
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.203
  [Host]               : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .NET 7.0             : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .NET Framework 4.6.2 : .NET Framework 4.8.1 (4.8.9139.0), X64 RyuJIT VectorSize=256
----
