== Resources

=== Documentation

* https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1.contains[HashSet<T>.Contains(T)]
* https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.sortedset-1.contains[SortedSet<T>.Contains(T)]
* https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.contains[List.Contains(T)]
* https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any[Enumerable.Any]
* https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/linq-to-entities[LINQ to Entities]

=== Articles & blog posts

* https://learn.microsoft.com/en-us/dotnet/standard/collections/[Collections and Data Structures]

=== Benchmarks

[options="header"]
|===
| Method                | Runtime              | Mean          | Standard Deviation | Allocated
|           HashSet_Any |             .NET 7.0 | 35,388.333 us |   620.1863 us |   40132 B
|      HashSet_Contains |             .NET 7.0 |      3.799 us |     0.1489 us |         -
|              List_Any |             .NET 7.0 | 32,851.509 us |   667.1658 us |   40130 B
|         List_Contains |             .NET 7.0 |    375.132 us |     8.0764 us |         -
|           HashSet_Any | .NET Framework 4.6.2 | 28,979.763 us |   678.0093 us |   40448 B
|      HashSet_Contains | .NET Framework 4.6.2 |      5.987 us |     0.1090 us |         -
|              List_Any | .NET Framework 4.6.2 | 25,830.221 us |   487.2470 us |   40448 B
|         List_Contains | .NET Framework 4.6.2 |  5,935.812 us |    57.7569 us |         -
|===

==== 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]
----
[Params(10_000)]
public int SampleSize;

[Params(1_000)]
public int Iterations;

private static HashSet<int> hashSet;
private static List<int> list;

[GlobalSetup]
public void Setup()
{
    hashSet = new HashSet<int>(Enumerable.Range(0, SampleSize));
    list = Enumerable.Range(0, SampleSize).ToList();
}

[Benchmark]
public void HashSet_Any() =>
    CheckAny(hashSet, SampleSize / 2);

[Benchmark]
public void HashSet_Contains() =>
    CheckContains(hashSet, SampleSize / 2);

[Benchmark]
public void List_Any() =>
    CheckAny(list, SampleSize / 2);

[Benchmark]
public void List_Contains() =>
    CheckContains(list, SampleSize / 2);

void CheckAny(IEnumerable<int> values, int target)
{
    for (int i = 0; i < Iterations; i++)
    {
        _ = values.Any(x => x == target);  // Enumerable.Any
    }
}

void CheckContains(ICollection<int> values, int target)
{
    for (int i = 0; i < Iterations; i++)
    {
        _ = values.Contains(target); // ICollection<T>.Contains
    }
}
----

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
----