{"id":19121086,"url":"https://github.com/dadhi/imtools","last_synced_at":"2025-05-15T04:04:20.756Z","repository":{"id":15369731,"uuid":"78003112","full_name":"dadhi/ImTools","owner":"dadhi","description":"Fast and memory-efficient immutable collections and helper data structures","archived":false,"fork":false,"pushed_at":"2024-11-02T15:11:12.000Z","size":8619,"stargazers_count":239,"open_issues_count":11,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-15T04:03:03.238Z","etag":null,"topics":["2-3-tree","avl-tree","compare-and-swap","data-structures","dictionary","effects","functional-programming","hashmap","hashtable","immutable","lock-free","map","memory-efficient","open-addressing","performance","persistent","reference-semantics","robinhood-hashmap","sum-types","value-semantics"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dadhi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"dadhi"}},"created_at":"2017-01-04T09:50:07.000Z","updated_at":"2025-05-07T15:49:10.000Z","dependencies_parsed_at":"2022-07-16T13:16:23.285Z","dependency_job_id":"97d26dfc-f10a-41a5-9c19-87c71b13b9ec","html_url":"https://github.com/dadhi/ImTools","commit_stats":{"total_commits":912,"total_committers":4,"mean_commits":228.0,"dds":"0.21052631578947367","last_synced_commit":"f6e2caa0dab8793f6f74a6f204c89d27d2c60741"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FImTools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FImTools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FImTools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FImTools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dadhi","download_url":"https://codeload.github.com/dadhi/ImTools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270641,"owners_count":22042858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2-3-tree","avl-tree","compare-and-swap","data-structures","dictionary","effects","functional-programming","hashmap","hashtable","immutable","lock-free","map","memory-efficient","open-addressing","performance","persistent","reference-semantics","robinhood-hashmap","sum-types","value-semantics"],"created_at":"2024-11-09T05:16:01.614Z","updated_at":"2025-05-15T04:04:20.667Z","avatar_url":"https://github.com/dadhi.png","language":"C#","readme":"# ImTools\n\nFast and memory-efficient immutable and mutable collections and helper data structures.\n\nInitially split from the [DryIoc](https://github.com/dadhi/dryioc), and now used in the [FastExpressionCompiler](https://github.com/dadhi/fastexpressioncompiler) too.\n\n[![license](https://img.shields.io/github/license/dadhi/ImTools.svg)](http://opensource.org/licenses/MIT)\n\n- Windows, Linux, MacOS [![CI build](https://ci.appveyor.com/api/projects/status/el9echuqfnl86u53?svg=true)](https://ci.appveyor.com/project/MaksimVolkau/imtools/branch/master)\n- Lib package [![NuGet Version](https://img.shields.io/nuget/v/ImTools.dll)](https://www.nuget.org/packages/ImTools.dll)![NuGet Downloads](https://img.shields.io/nuget/dt/ImTools.dll)\n- Code package [![NuGet Version](https://img.shields.io/nuget/v/ImTools)](https://www.nuget.org/packages/ImTools)![NuGet Downloads](https://img.shields.io/nuget/dt/ImTools)\n- Latest release [![latest release](https://img.shields.io/badge/latest%20release-v4.0.0-green)](https://github.com/dadhi/ImTools/releases/tag/v4.0.0) \n\n\n## Benchmarks\n\nThe comparison is done against the previous versions and the variety of BCL C# collections including the experimental `Microsoft.Collections.Extensions.DictionarySlim\u003cK, V\u003e`.\n\n__Important:__ Keep in mind that immutable collections have a different use-case and a thread-safety guarantees compared to the \n`Dictionary`, `DictionarySlim` or even `ConcurrentDictionary`. The closest comparable would be the `ImmutableDictionary`. \nThe benchmarks do not take the collections \"nature\" into account and run through the simplest available API path.\n\n\n### ImHashMap of Type keys and small string values\n\n#### Population\n\n[The benchmark](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImHashMapBenchmarks.cs) inserts from 10 to 1000\nitems into the `ImHashMap\u003cType, string\u003e`:\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                            | Count |          Mean |        Error |       StdDev | Ratio | RatioSD |    Gen 0 |   Gen 1 | Gen 2 | Allocated |\n| --------------------------------- | ----- | ------------: | -----------: | -----------: | ----: | ------: | -------: | ------: | ----: | --------: |\n| V4_ImHashMap_AddOrUpdate          | 1     |      33.32 ns |     0.439 ns |     0.389 ns |  1.00 |    0.00 |   0.0178 |       - |     - |     112 B |\n| V3_ImHashMap_AddOrUpdate          | 1     |      35.97 ns |     0.639 ns |     0.567 ns |  1.08 |    0.02 |   0.0178 |       - |     - |     112 B |\n| V4_PartitionedHashMap_AddOrUpdate | 1     |      97.72 ns |     1.294 ns |     1.148 ns |  2.93 |    0.05 |   0.0370 |       - |     - |     232 B |\n| DictSlim_TryAdd                   | 1     |      59.37 ns |     0.519 ns |     0.434 ns |  1.78 |    0.02 |   0.0229 |       - |     - |     144 B |\n| Dict_TryAdd                       | 1     |      65.94 ns |     0.631 ns |     0.560 ns |  1.98 |    0.02 |   0.0343 |       - |     - |     216 B |\n| ConcurrentDictionary_TryAdd       | 1     |     197.29 ns |     1.883 ns |     1.761 ns |  5.92 |    0.09 |   0.1466 |  0.0007 |     - |     920 B |\n| ImmutableDict_Builder_Add         | 1     |     220.79 ns |     2.648 ns |     2.477 ns |  6.62 |    0.10 |   0.0355 |       - |     - |     224 B |\n| ImmutableDict_Add                 | 1     |     264.15 ns |     4.786 ns |     3.737 ns |  7.93 |    0.16 |   0.0429 |       - |     - |     272 B |\n|                                   |       |               |              |              |       |         |          |         |       |           |\n| V4_ImHashMap_AddOrUpdate          | 10    |     307.91 ns |     5.281 ns |     4.940 ns |  1.00 |    0.00 |   0.1564 |  0.0005 |     - |     984 B |\n| V3_ImHashMap_AddOrUpdate          | 10    |     389.09 ns |     6.482 ns |     5.746 ns |  1.27 |    0.03 |   0.1593 |  0.0005 |     - |    1000 B |\n| V4_PartitionedHashMap_AddOrUpdate | 10    |     392.47 ns |     4.296 ns |     5.276 ns |  1.27 |    0.03 |   0.1144 |  0.0005 |     - |     720 B |\n| DictSlim_TryAdd                   | 10    |     409.45 ns |     2.216 ns |     1.965 ns |  1.33 |    0.02 |   0.1707 |  0.0005 |     - |    1072 B |\n| Dict_TryAdd                       | 10    |     413.38 ns |     5.460 ns |     5.107 ns |  1.34 |    0.03 |   0.1578 |  0.0005 |     - |     992 B |\n| ConcurrentDictionary_TryAdd       | 10    |   1,319.88 ns |    20.332 ns |    19.019 ns |  4.29 |    0.11 |   0.4730 |  0.0076 |     - |    2968 B |\n| ImmutableDict_Builder_Add         | 10    |   1,712.26 ns |    15.264 ns |    26.733 ns |  5.59 |    0.12 |   0.1259 |       - |     - |     800 B |\n| ImmutableDict_Add                 | 10    |   2,986.38 ns |    17.824 ns |    14.884 ns |  9.70 |    0.18 |   0.4349 |       - |     - |    2744 B |\n|                                   |       |               |              |              |       |         |          |         |       |           |\n| V4_ImHashMap_AddOrUpdate          | 100   |   9,188.79 ns |   116.272 ns |   108.761 ns |  1.00 |    0.00 |   2.8229 |  0.0916 |     - |   17792 B |\n| V3_ImHashMap_AddOrUpdate          | 100   |  10,591.30 ns |   169.894 ns |   141.869 ns |  1.15 |    0.03 |   3.1891 |  0.1068 |     - |   20032 B |\n| V4_PartitionedHashMap_AddOrUpdate | 100   |   4,491.75 ns |    81.205 ns |    75.959 ns |  0.49 |    0.01 |   1.2360 |  0.0534 |     - |    7776 B |\n| DictSlim_TryAdd                   | 100   |   3,201.77 ns |    48.216 ns |    42.743 ns |  0.35 |    0.01 |   1.1902 |  0.0305 |     - |    7488 B |\n| Dict_TryAdd                       | 100   |   3,856.61 ns |    70.806 ns |    62.768 ns |  0.42 |    0.01 |   1.6174 |  0.0687 |     - |   10192 B |\n| ConcurrentDictionary_TryAdd       | 100   |  16,035.70 ns |   320.350 ns |   356.068 ns |  1.75 |    0.04 |   4.9133 |  0.5798 |     - |   30824 B |\n| ImmutableDict_Builder_Add         | 100   |  24,427.83 ns |   470.630 ns |   417.201 ns |  2.66 |    0.07 |   1.0376 |  0.0305 |     - |    6560 B |\n| ImmutableDict_Add                 | 100   |  48,772.32 ns |   687.894 ns |   574.422 ns |  5.30 |    0.10 |   7.1411 |  0.2441 |     - |   44936 B |\n|                                   |       |               |              |              |       |         |          |         |       |           |\n| V4_ImHashMap_AddOrUpdate          | 1000  | 277,024.17 ns | 3,349.815 ns | 2,969.524 ns |  1.00 |    0.00 |  45.4102 | 10.7422 |     - |  286344 B |\n| V3_ImHashMap_AddOrUpdate          | 1000  | 234,444.41 ns | 2,324.332 ns | 1,940.923 ns |  0.85 |    0.01 |  51.5137 | 12.2070 |     - |  324176 B |\n| V4_PartitionedHashMap_AddOrUpdate | 1000  | 146,984.47 ns |   954.053 ns |   845.743 ns |  0.53 |    0.01 |  26.1230 |  7.5684 |     - |  164280 B |\n| DictSlim_TryAdd                   | 1000  |  33,447.54 ns |   254.743 ns |   225.823 ns |  0.12 |    0.00 |   9.1553 |  1.7700 |     - |   57808 B |\n| Dict_TryAdd                       | 1000  |  40,234.23 ns |   430.048 ns |   381.226 ns |  0.15 |    0.00 |  16.2354 |  5.3711 |     - |  102216 B |\n| ConcurrentDictionary_TryAdd       | 1000  | 165,018.54 ns | 3,075.862 ns | 2,568.484 ns |  0.60 |    0.01 |  41.2598 | 13.6719 |     - |  259720 B |\n| ImmutableDict_Builder_Add         | 1000  | 396,623.48 ns | 4,099.094 ns | 3,834.295 ns |  1.43 |    0.02 |   9.7656 |  2.4414 |     - |   64160 B |\n| ImmutableDict_Add                 | 1000  | 813,397.08 ns | 9,203.453 ns | 8,608.916 ns |  2.94 |    0.04 | 105.4688 | 25.3906 |     - |  665001 B |\n```\n\n### Lookup\n\n[The benchmark](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImHashMapBenchmarks.cs) lookups for the specific key in the \n`ImHashMap\u003cType, string\u003e` containing the specified Count of elements.\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                           | Count |      Mean |     Error |    StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |\n| -------------------------------- | ----- | --------: | --------: | --------: | ----: | ------: | ----: | ----: | ----: | --------: |\n| V4_ImHashMap_TryFind             | 1     |  8.915 ns | 0.1853 ns | 0.1733 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V3_ImHashMap_TryFind             | 1     |  7.834 ns | 0.1769 ns | 0.1568 ns |  0.88 |    0.02 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind    | 1     |  8.292 ns | 0.1082 ns | 0.0959 ns |  0.93 |    0.02 |     - |     - |     - |         - |\n| V3_PartitionedHashMap_TryFind    | 1     |  7.681 ns | 0.1245 ns | 0.1039 ns |  0.86 |    0.02 |     - |     - |     - |         - |\n| DictionarySlim_TryGetValue       | 1     |  8.861 ns | 0.1423 ns | 0.1188 ns |  0.99 |    0.02 |     - |     - |     - |         - |\n| Dictionary_TryGetValue           | 1     | 17.914 ns | 0.3447 ns | 0.3055 ns |  2.01 |    0.05 |     - |     - |     - |         - |\n| ConcurrentDictionary_TryGetValue | 1     | 13.381 ns | 0.2709 ns | 0.2401 ns |  1.50 |    0.04 |     - |     - |     - |         - |\n| ImmutableDict_TryGet             | 1     | 19.040 ns | 0.3068 ns | 0.2870 ns |  2.14 |    0.06 |     - |     - |     - |         - |\n|                                  |       |           |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind             | 10    |  9.462 ns | 0.2690 ns | 0.2246 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V3_ImHashMap_TryFind             | 10    |  9.038 ns | 0.1650 ns | 0.1463 ns |  0.96 |    0.02 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind    | 10    |  8.575 ns | 0.2031 ns | 0.1900 ns |  0.91 |    0.03 |     - |     - |     - |         - |\n| V3_PartitionedHashMap_TryFind    | 10    |  5.869 ns | 0.1026 ns | 0.1743 ns |  0.63 |    0.02 |     - |     - |     - |         - |\n| DictionarySlim_TryGetValue       | 10    |  7.384 ns | 0.1882 ns | 0.1668 ns |  0.78 |    0.03 |     - |     - |     - |         - |\n| Dictionary_TryGetValue           | 10    | 14.082 ns | 0.2168 ns | 0.1921 ns |  1.49 |    0.04 |     - |     - |     - |         - |\n| ConcurrentDictionary_TryGetValue | 10    | 11.436 ns | 0.1398 ns | 0.1239 ns |  1.21 |    0.03 |     - |     - |     - |         - |\n| ImmutableDict_TryGet             | 10    | 17.927 ns | 0.4467 ns | 0.4780 ns |  1.90 |    0.09 |     - |     - |     - |         - |\n|                                  |       |           |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind             | 100   | 12.147 ns | 0.1475 ns | 0.1308 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V3_ImHashMap_TryFind             | 100   | 11.357 ns | 0.1695 ns | 0.1323 ns |  0.94 |    0.01 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind    | 100   |  8.520 ns | 0.2142 ns | 0.1899 ns |  0.70 |    0.02 |     - |     - |     - |         - |\n| V3_PartitionedHashMap_TryFind    | 100   |  7.785 ns | 0.1374 ns | 0.1147 ns |  0.64 |    0.01 |     - |     - |     - |         - |\n| DictionarySlim_TryGetValue       | 100   |  6.918 ns | 0.1544 ns | 0.1289 ns |  0.57 |    0.01 |     - |     - |     - |         - |\n| Dictionary_TryGetValue           | 100   | 13.804 ns | 0.3474 ns | 0.3717 ns |  1.14 |    0.04 |     - |     - |     - |         - |\n| ConcurrentDictionary_TryGetValue | 100   | 11.432 ns | 0.2194 ns | 0.2052 ns |  0.94 |    0.02 |     - |     - |     - |         - |\n| ImmutableDict_TryGet             | 100   | 21.593 ns | 0.4048 ns | 0.3786 ns |  1.78 |    0.03 |     - |     - |     - |         - |\n|                                  |       |           |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind             | 1000  | 15.492 ns | 0.3859 ns | 0.4881 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V3_ImHashMap_TryFind             | 1000  | 14.339 ns | 0.2612 ns | 0.2444 ns |  0.92 |    0.03 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind    | 1000  | 11.508 ns | 0.1839 ns | 0.1630 ns |  0.74 |    0.03 |     - |     - |     - |         - |\n| V3_PartitionedHashMap_TryFind    | 1000  |  9.508 ns | 0.2340 ns | 0.2074 ns |  0.61 |    0.02 |     - |     - |     - |         - |\n| DictionarySlim_TryGetValue       | 1000  |  7.099 ns | 0.1984 ns | 0.2037 ns |  0.46 |    0.01 |     - |     - |     - |         - |\n| Dictionary_TryGetValue           | 1000  | 13.696 ns | 0.1341 ns | 0.1120 ns |  0.88 |    0.03 |     - |     - |     - |         - |\n| ConcurrentDictionary_TryGetValue | 1000  | 11.358 ns | 0.1464 ns | 0.1222 ns |  0.73 |    0.03 |     - |     - |     - |         - |\n| ImmutableDict_TryGet             | 1000  | 25.875 ns | 0.3752 ns | 0.3510 ns |  1.67 |    0.06 |     - |     - |     - |         - |\n```\n\n### Enumeration\n\n[The benchmark source](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImHashMapBenchmarks.cs)\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                          | Count |         Mean |      Error |     StdDev |       Median | Ratio | RatioSD |  Gen 0 | Gen 1 | Gen 2 | Allocated |\n| ------------------------------- | ----- | -----------: | ---------: | ---------: | -----------: | ----: | ------: | -----: | ----: | ----: | --------: |\n| V4_ImHashMap_Enumerate          | 1     |     39.51 ns |   0.865 ns |   0.996 ns |     39.43 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V3_ImHashMap_Enumerate          | 1     |     44.11 ns |   0.879 ns |   0.822 ns |     44.28 ns |  1.12 |    0.04 | 0.0255 |     - |     - |     160 B |\n| V4_PartitionedHashMap_Enumerate | 1     |    118.94 ns |   1.644 ns |   1.538 ns |    118.91 ns |  3.01 |    0.09 |      - |     - |     - |         - |\n| V3_PartitionedHashMap_Enumerate | 1     |    180.82 ns |   3.462 ns |   3.238 ns |    181.09 ns |  4.57 |    0.14 | 0.0522 |     - |     - |     328 B |\n| DictionarySlim_Enumerate        | 1     |     12.77 ns |   0.254 ns |   0.238 ns |     12.76 ns |  0.32 |    0.01 |      - |     - |     - |         - |\n| Dictionary_Enumerate            | 1     |     15.24 ns |   0.652 ns |   1.817 ns |     14.36 ns |  0.46 |    0.05 |      - |     - |     - |         - |\n| ConcurrentDictionary_foreach    | 1     |    177.04 ns |   2.073 ns |   1.939 ns |    176.68 ns |  4.47 |    0.12 | 0.0100 |     - |     - |      64 B |\n| ImmutableDict_Enumerate         | 1     |    161.96 ns |   0.760 ns |   0.635 ns |    161.98 ns |  4.08 |    0.12 |      - |     - |     - |         - |\n|                                 |       |              |            |            |              |       |         |        |       |       |           |\n| V4_ImHashMap_Enumerate          | 10    |    191.91 ns |   3.010 ns |   2.668 ns |    192.57 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V3_ImHashMap_Enumerate          | 10    |    223.10 ns |   1.885 ns |   1.574 ns |    223.12 ns |  1.16 |    0.02 | 0.0381 |     - |     - |     240 B |\n| V4_PartitionedHashMap_Enumerate | 10    |    379.75 ns |   4.543 ns |   4.027 ns |    379.74 ns |  1.98 |    0.03 |      - |     - |     - |         - |\n| V3_PartitionedHashMap_Enumerate | 10    |    604.47 ns |   4.257 ns |   3.774 ns |    603.87 ns |  3.15 |    0.05 | 0.1793 |     - |     - |    1128 B |\n| DictionarySlim_Enumerate        | 10    |     73.15 ns |   1.438 ns |   1.345 ns |     72.82 ns |  0.38 |    0.01 |      - |     - |     - |         - |\n| Dictionary_Enumerate            | 10    |     57.95 ns |   0.749 ns |   0.701 ns |     57.86 ns |  0.30 |    0.01 |      - |     - |     - |         - |\n| ConcurrentDictionary_foreach    | 10    |    505.36 ns |   7.959 ns |   7.445 ns |    504.00 ns |  2.64 |    0.05 | 0.0095 |     - |     - |      64 B |\n| ImmutableDict_Enumerate         | 10    |    556.35 ns |  10.730 ns |   9.512 ns |    558.53 ns |  2.90 |    0.06 |      - |     - |     - |         - |\n|                                 |       |              |            |            |              |       |         |        |       |       |           |\n| V4_ImHashMap_Enumerate          | 100   |  2,023.65 ns |  33.506 ns |  29.702 ns |  2,031.78 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V3_ImHashMap_Enumerate          | 100   |  1,992.46 ns |  23.400 ns |  20.744 ns |  1,992.05 ns |  0.98 |    0.02 | 0.0381 |     - |     - |     240 B |\n| V4_PartitionedHashMap_Enumerate | 100   |  2,626.85 ns |  42.089 ns |  37.311 ns |  2,616.34 ns |  1.30 |    0.02 |      - |     - |     - |         - |\n| V3_PartitionedHashMap_Enumerate | 100   |  3,469.16 ns |  30.415 ns |  26.962 ns |  3,469.32 ns |  1.71 |    0.03 | 0.4349 |     - |     - |    2728 B |\n| DictionarySlim_Enumerate        | 100   |    615.29 ns |  10.217 ns |   9.057 ns |    617.89 ns |  0.30 |    0.01 |      - |     - |     - |         - |\n| Dictionary_Enumerate            | 100   |    578.30 ns |   3.310 ns |   2.764 ns |    578.14 ns |  0.29 |    0.00 |      - |     - |     - |         - |\n| ConcurrentDictionary_foreach    | 100   |  3,444.60 ns |  55.779 ns |  52.176 ns |  3,425.75 ns |  1.70 |    0.03 | 0.0076 |     - |     - |      64 B |\n| ImmutableDict_Enumerate         | 100   |  4,557.81 ns |  71.187 ns |  63.105 ns |  4,552.69 ns |  2.25 |    0.03 |      - |     - |     - |         - |\n|                                 |       |              |            |            |              |       |         |        |       |       |           |\n| V4_ImHashMap_Enumerate          | 1000  | 22,259.46 ns | 204.173 ns | 180.994 ns | 22,241.67 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V3_ImHashMap_Enumerate          | 1000  | 21,710.99 ns | 288.512 ns | 240.921 ns | 21,770.78 ns |  0.98 |    0.02 | 0.0610 |     - |     - |     480 B |\n| V4_PartitionedHashMap_Enumerate | 1000  | 28,097.70 ns | 392.513 ns | 306.449 ns | 28,134.91 ns |  1.26 |    0.02 |      - |     - |     - |         - |\n| V3_PartitionedHashMap_Enumerate | 1000  | 31,132.68 ns | 473.705 ns | 443.104 ns | 31,208.71 ns |  1.40 |    0.01 | 0.4272 |     - |     - |    2728 B |\n| DictionarySlim_Enumerate        | 1000  |  6,472.19 ns |  53.546 ns |  47.467 ns |  6,482.73 ns |  0.29 |    0.00 |      - |     - |     - |         - |\n| Dictionary_Enumerate            | 1000  |  5,700.68 ns |  65.696 ns |  61.452 ns |  5,698.15 ns |  0.26 |    0.00 |      - |     - |     - |         - |\n| ConcurrentDictionary_foreach    | 1000  | 43,550.74 ns | 848.746 ns | 752.391 ns | 43,765.79 ns |  1.96 |    0.04 |      - |     - |     - |      64 B |\n| ImmutableDict_Enumerate         | 1000  | 46,089.57 ns | 524.157 ns | 464.651 ns | 46,183.41 ns |  2.07 |    0.03 |      - |     - |     - |         - |\n```\n\n\n### ImHashMap with int keys and small string values\n\n`ImHashMap\u003cint, string\u003e` stores the `int` keys and `string` values.\n\n\n#### Population\n\n[The benchmark](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImMapBenchmarks.cs) inserts from 1 to 10 000 of items into the `ImHashMap\u003cint, string\u003e`:\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                          | Count |             Mean |          Error |         StdDev |           Median | Ratio | RatioSD |     Gen 0 |    Gen 1 |    Gen 2 | Allocated |\n| ------------------------------- | ----- | ---------------: | -------------: | -------------: | ---------------: | ----: | ------: | --------: | -------: | -------: | --------: |\n| V4_ImHashMap_AddOrUpdate        | 1     |         13.30 ns |       0.296 ns |       0.277 ns |         13.30 ns |  1.00 |    0.00 |    0.0051 |        - |        - |      32 B |\n| V2_ImMap_AddOrUpdate            | 1     |         17.09 ns |       0.207 ns |       0.184 ns |         17.08 ns |  1.28 |    0.03 |    0.0076 |        - |        - |      48 B |\n| V4_PartitionedImMap_AddOrUpdate | 1     |         79.98 ns |       1.023 ns |       1.467 ns |         79.66 ns |  6.04 |    0.16 |    0.0293 |        - |        - |     184 B |\n| DictSlim_GetOrAddValueRef       | 1     |         41.18 ns |       0.416 ns |       0.369 ns |         41.28 ns |  3.10 |    0.08 |    0.0204 |        - |        - |     128 B |\n| Dict_TryAdd                     | 1     |         37.06 ns |       0.418 ns |       0.370 ns |         37.08 ns |  2.79 |    0.06 |    0.0344 |        - |        - |     216 B |\n| ConcurrentDict_TryAdd           | 1     |        146.05 ns |       2.124 ns |       1.773 ns |        145.64 ns | 10.95 |    0.27 |    0.1376 |   0.0007 |        - |     864 B |\n| ImmutableDict_Builder_Add       | 1     |        120.60 ns |       0.788 ns |       0.658 ns |        120.43 ns |  9.05 |    0.20 |    0.0253 |        - |        - |     160 B |\n| ImmutableDict_Add               | 1     |        107.37 ns |       1.833 ns |       2.384 ns |        106.71 ns |  8.11 |    0.25 |    0.0166 |        - |        - |     104 B |\n|                                 |       |                  |                |                |                  |       |         |           |          |          |           |\n| V4_ImHashMap_AddOrUpdate        | 10    |        229.89 ns |       1.484 ns |       1.239 ns |        230.08 ns |  1.00 |    0.00 |    0.1173 |        - |        - |     736 B |\n| V2_ImMap_AddOrUpdate            | 10    |        551.17 ns |       4.425 ns |       3.695 ns |        550.33 ns |  2.40 |    0.02 |    0.2823 |        - |        - |    1776 B |\n| V4_PartitionedImMap_AddOrUpdate | 10    |        242.93 ns |       4.599 ns |       3.840 ns |        242.93 ns |  1.06 |    0.02 |    0.0749 |        - |        - |     472 B |\n| DictSlim_GetOrAddValueRef       | 10    |        281.33 ns |       5.547 ns |       5.935 ns |        280.41 ns |  1.22 |    0.03 |    0.1326 |        - |        - |     832 B |\n| Dict_TryAdd                     | 10    |        258.89 ns |       3.412 ns |       3.025 ns |        258.85 ns |  1.13 |    0.01 |    0.1578 |   0.0005 |        - |     992 B |\n| ConcurrentDict_TryAdd           | 10    |        540.34 ns |       3.092 ns |       2.741 ns |        539.06 ns |  2.35 |    0.01 |    0.1945 |   0.0010 |        - |    1224 B |\n| ImmutableDict_Builder_Add       | 10    |      1,514.60 ns |       8.675 ns |       7.244 ns |      1,513.34 ns |  6.59 |    0.05 |    0.1163 |        - |        - |     736 B |\n| ImmutableDict_Add               | 10    |      2,632.30 ns |      51.955 ns |      48.599 ns |      2,639.68 ns | 11.45 |    0.22 |    0.4196 |        - |        - |    2640 B |\n|                                 |       |                  |                |                |                  |       |         |           |          |          |           |\n| V4_ImHashMap_AddOrUpdate        | 100   |      8,221.37 ns |     125.831 ns |     117.703 ns |      8,192.32 ns |  1.00 |    0.00 |    2.9602 |   0.1221 |        - |   18640 B |\n| V2_ImMap_AddOrUpdate            | 100   |     12,184.44 ns |     179.889 ns |     168.268 ns |     12,140.26 ns |  1.48 |    0.02 |    5.9357 |   0.2441 |        - |   37296 B |\n| V4_PartitionedImMap_AddOrUpdate | 100   |      3,370.45 ns |      23.906 ns |      18.664 ns |      3,363.21 ns |  0.41 |    0.01 |    1.4801 |   0.0839 |        - |    9304 B |\n| DictSlim_GetOrAddValueRef       | 100   |      2,652.96 ns |      37.693 ns |      35.258 ns |      2,649.32 ns |  0.32 |    0.00 |    1.3275 |   0.0534 |        - |    8336 B |\n| Dict_TryAdd                     | 100   |      2,828.22 ns |      21.898 ns |      19.412 ns |      2,826.77 ns |  0.34 |    0.01 |    2.0828 |   0.1297 |        - |   13072 B |\n| ConcurrentDict_TryAdd           | 100   |     10,866.25 ns |     111.428 ns |     104.229 ns |     10,909.92 ns |  1.32 |    0.02 |    3.6316 |   0.3510 |        - |   22784 B |\n| ImmutableDict_Builder_Add       | 100   |     25,598.91 ns |     273.166 ns |     255.520 ns |     25,525.67 ns |  3.11 |    0.06 |    1.4648 |   0.0916 |        - |    9376 B |\n| ImmutableDict_Add               | 100   |     46,542.15 ns |     412.627 ns |     344.562 ns |     46,612.94 ns |  5.68 |    0.09 |    7.9346 |   0.3662 |        - |   49952 B |\n|                                 |       |                  |                |                |                  |       |         |           |          |          |           |\n| V4_ImHashMap_AddOrUpdate        | 1000  |    152,860.18 ns |   1,517.703 ns |   1,345.404 ns |    152,745.43 ns |  1.00 |    0.00 |   46.6309 |   0.4883 |        - |  293656 B |\n| V2_ImMap_AddOrUpdate            | 1000  |    198,915.64 ns |   2,889.932 ns |   2,561.850 ns |    198,557.64 ns |  1.30 |    0.02 |   84.9609 |   0.2441 |        - |  534144 B |\n| V4_PartitionedImMap_AddOrUpdate | 1000  |     83,983.62 ns |   1,391.788 ns |   1,301.880 ns |     83,699.54 ns |  0.55 |    0.01 |   27.0996 |   9.0332 |        - |  170456 B |\n| DictSlim_GetOrAddValueRef       | 1000  |     26,659.61 ns |     349.284 ns |     326.721 ns |     26,615.57 ns |  0.17 |    0.00 |   11.6272 |   2.8992 |        - |   73120 B |\n| Dict_TryAdd                     | 1000  |     31,317.33 ns |     475.471 ns |     444.756 ns |     31,251.40 ns |  0.21 |    0.00 |   21.2402 |   0.0610 |        - |  133896 B |\n| ConcurrentDict_TryAdd           | 1000  |    112,582.19 ns |   1,221.657 ns |   1,082.967 ns |    112,203.70 ns |  0.74 |    0.01 |   32.7148 |   0.1221 |        - |  205368 B |\n| ImmutableDict_Builder_Add       | 1000  |    350,888.85 ns |   3,757.786 ns |   3,515.035 ns |    352,417.77 ns |  2.30 |    0.03 |   15.1367 |   4.8828 |        - |   95776 B |\n| ImmutableDict_Add               | 1000  |    692,782.78 ns |   5,756.492 ns |   5,102.980 ns |    694,477.10 ns |  4.53 |    0.05 |  112.3047 |   0.9766 |        - |  710209 B |\n|                                 |       |                  |                |                |                  |       |         |           |          |          |           |\n| V4_ImHashMap_AddOrUpdate        | 10000 |  3,879,586.59 ns |  64,823.212 ns |  60,635.673 ns |  3,882,537.11 ns |  1.00 |    0.00 |  632.8125 | 312.5000 |  46.8750 | 3993786 B |\n| V2_ImMap_AddOrUpdate            | 10000 |  4,485,663.73 ns |  54,179.233 ns |  45,242.113 ns |  4,483,992.58 ns |  1.16 |    0.02 | 1109.3750 | 226.5625 | 101.5625 | 6972711 B |\n| V4_PartitionedImMap_AddOrUpdate | 10000 |  2,822,478.66 ns |  49,570.016 ns |  85,505.842 ns |  2,806,964.45 ns |  0.73 |    0.04 |  433.5938 | 214.8438 |        - | 2720602 B |\n| DictSlim_GetOrAddValueRef       | 10000 |    424,813.34 ns |   2,027.361 ns |   1,797.203 ns |    424,378.52 ns |  0.11 |    0.00 |  124.5117 | 124.5117 | 124.5117 |  975754 B |\n| Dict_TryAdd                     | 10000 |    526,320.80 ns |   9,338.940 ns |   8,278.727 ns |    523,071.63 ns |  0.14 |    0.00 |  221.6797 | 221.6797 | 221.6797 | 1261763 B |\n| ConcurrentDict_TryAdd           | 10000 |  2,721,195.59 ns |  62,415.534 ns | 182,069.041 ns |  2,805,224.80 ns |  0.72 |    0.04 |  273.4375 | 121.0938 |  42.9688 | 1645328 B |\n| ImmutableDict_Builder_Add       | 10000 |  4,653,773.55 ns |  48,265.920 ns |  42,786.481 ns |  4,645,701.95 ns |  1.20 |    0.02 |  148.4375 |  70.3125 |        - |  959781 B |\n| ImmutableDict_Add               | 10000 | 10,911,107.09 ns | 101,847.861 ns |  85,047.577 ns | 10,956,526.56 ns |  2.81 |    0.04 | 1468.7500 | 265.6250 | 125.0000 | 9271220 B |\n```\n\n\n#### Lookup\n\n[The benchmark](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImMapBenchmarks.cs) lookups for the last added index in the `ImHashMap\u003cint, string\u003e` \ncontaining the specified Count of elements.\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                        | Count |       Mean |     Error |    StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |\n| ----------------------------- | ----- | ---------: | --------: | --------: | ----: | ------: | ----: | ----: | ----: | --------: |\n| V4_ImHashMap_TryFind          | 1     |  2.5662 ns | 0.0840 ns | 0.0701 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind | 1     |  2.9264 ns | 0.0775 ns | 0.0687 ns |  1.14 |    0.03 |     - |     - |     - |         - |\n| V2_ImMap_TryFind              | 1     |  0.8574 ns | 0.0826 ns | 0.0772 ns |  0.33 |    0.02 |     - |     - |     - |         - |\n| DictSlim_TryGetValue          | 1     |  3.7989 ns | 0.1118 ns | 0.1046 ns |  1.48 |    0.05 |     - |     - |     - |         - |\n| Dict_TryGetValue              | 1     |  7.5973 ns | 0.2095 ns | 0.1857 ns |  2.95 |    0.08 |     - |     - |     - |         - |\n| ConcurrentDict_TryGetValue    | 1     |  8.1365 ns | 0.1859 ns | 0.1552 ns |  3.17 |    0.08 |     - |     - |     - |         - |\n| ImmutableDict_TryGetValue     | 1     | 15.7728 ns | 0.3912 ns | 0.4348 ns |  6.16 |    0.25 |     - |     - |     - |         - |\n|                               |       |            |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind          | 10    |  3.0618 ns | 0.0535 ns | 0.0474 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind | 10    |  2.5114 ns | 0.1019 ns | 0.0851 ns |  0.82 |    0.02 |     - |     - |     - |         - |\n| V2_ImMap_TryFind              | 10    |  3.5793 ns | 0.1092 ns | 0.1022 ns |  1.17 |    0.04 |     - |     - |     - |         - |\n| DictSlim_TryGetValue          | 10    |  4.0213 ns | 0.0329 ns | 0.0275 ns |  1.31 |    0.02 |     - |     - |     - |         - |\n| Dict_TryGetValue              | 10    |  6.9583 ns | 0.0809 ns | 0.0717 ns |  2.27 |    0.03 |     - |     - |     - |         - |\n| ConcurrentDict_TryGetValue    | 10    |  7.9926 ns | 0.0997 ns | 0.0884 ns |  2.61 |    0.05 |     - |     - |     - |         - |\n| ImmutableDict_TryGetValue     | 10    | 17.5147 ns | 0.3430 ns | 0.3209 ns |  5.72 |    0.15 |     - |     - |     - |         - |\n|                               |       |            |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind          | 100   |  6.9090 ns | 0.1161 ns | 0.1030 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind | 100   |  2.6762 ns | 0.0542 ns | 0.1045 ns |  0.39 |    0.02 |     - |     - |     - |         - |\n| V2_ImMap_TryFind              | 100   |  7.1365 ns | 0.1727 ns | 0.1442 ns |  1.03 |    0.03 |     - |     - |     - |         - |\n| DictSlim_TryGetValue          | 100   |  4.4196 ns | 0.0861 ns | 0.0719 ns |  0.64 |    0.01 |     - |     - |     - |         - |\n| Dict_TryGetValue              | 100   |  7.6746 ns | 0.0770 ns | 0.0643 ns |  1.11 |    0.02 |     - |     - |     - |         - |\n| ConcurrentDict_TryGetValue    | 100   |  8.0521 ns | 0.1363 ns | 0.1138 ns |  1.17 |    0.03 |     - |     - |     - |         - |\n| ImmutableDict_TryGetValue     | 100   | 19.5683 ns | 0.1622 ns | 0.1355 ns |  2.83 |    0.04 |     - |     - |     - |         - |\n|                               |       |            |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind          | 1000  | 12.7430 ns | 0.2270 ns | 0.2123 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind | 1000  |  7.0856 ns | 0.0987 ns | 0.0824 ns |  0.55 |    0.01 |     - |     - |     - |         - |\n| V2_ImMap_TryFind              | 1000  | 10.9892 ns | 0.2986 ns | 0.3067 ns |  0.86 |    0.02 |     - |     - |     - |         - |\n| DictSlim_TryGetValue          | 1000  |  4.3216 ns | 0.1560 ns | 0.1459 ns |  0.34 |    0.01 |     - |     - |     - |         - |\n| Dict_TryGetValue              | 1000  |  7.9061 ns | 0.1667 ns | 0.1478 ns |  0.62 |    0.02 |     - |     - |     - |         - |\n| ConcurrentDict_TryGetValue    | 1000  |  8.1644 ns | 0.1095 ns | 0.0914 ns |  0.64 |    0.02 |     - |     - |     - |         - |\n| ImmutableDict_TryGetValue     | 1000  | 22.1566 ns | 0.2936 ns | 0.2603 ns |  1.74 |    0.03 |     - |     - |     - |         - |\n|                               |       |            |           |           |       |         |       |       |       |           |\n| V4_ImHashMap_TryFind          | 10000 | 17.4170 ns | 0.2906 ns | 0.2576 ns |  1.00 |    0.00 |     - |     - |     - |         - |\n| V4_PartitionedHashMap_TryFind | 10000 | 11.0928 ns | 0.1834 ns | 0.1626 ns |  0.64 |    0.01 |     - |     - |     - |         - |\n| V2_ImMap_TryFind              | 10000 | 15.6074 ns | 0.2325 ns | 0.2175 ns |  0.90 |    0.02 |     - |     - |     - |         - |\n| DictSlim_TryGetValue          | 10000 |  4.4326 ns | 0.1312 ns | 0.1228 ns |  0.25 |    0.01 |     - |     - |     - |         - |\n| Dict_TryGetValue              | 10000 |  7.5615 ns | 0.0669 ns | 0.0559 ns |  0.43 |    0.01 |     - |     - |     - |         - |\n| ConcurrentDict_TryGetValue    | 10000 |  7.5147 ns | 0.1537 ns | 0.1437 ns |  0.43 |    0.01 |     - |     - |     - |         - |\n| ImmutableDict_TryGetValue     | 10000 | 37.8435 ns | 0.4362 ns | 0.4080 ns |  2.17 |    0.04 |     - |     - |     - |         - |\n```\n\n**Interpreting results:** `ImHashMap` holds very good against `ImmutableDictionary` sibling and even against `Dictionary`(s) \n(especially if we are talking about PartitionedImHashMap) up to certain count, indicating that immutable collection could be \nquite fast for lookups.\n\n\n#### Enumeration\n\n[The benchmark source code](https://github.com/dadhi/ImTools/blob/master/playground/ImTools.Benchmarks/ImMapBenchmarks.cs)\n\n```md\nBenchmarkDotNet=v0.12.1, OS=Windows 10.0.19043\nIntel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores\n.NET Core SDK=6.0.202\n  [Host]     : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n  DefaultJob : .NET Core 6.0.4 (CoreCLR 6.0.422.16404, CoreFX 6.0.422.16404), X64 RyuJIT\n\n| Method                        | Count |          Mean |        Error |        StdDev | Ratio | RatioSD |  Gen 0 | Gen 1 | Gen 2 | Allocated |\n| ----------------------------- | ----- | ------------: | -----------: | ------------: | ----: | ------: | -----: | ----: | ----: | --------: |\n| V4_HashMap_foreach            | 1     |      39.92 ns |     0.820 ns |      0.767 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V4_PartitionedHashMap_foreach | 1     |     116.81 ns |     1.450 ns |      1.286 ns |  2.93 |    0.06 |      - |     - |     - |         - |\n| V2_ImMap_Enumerate            | 1     |      23.93 ns |     0.346 ns |      0.306 ns |  0.60 |    0.01 | 0.0114 |     - |     - |      72 B |\n| DictSlim_foreach              | 1     |      12.08 ns |     0.160 ns |      0.133 ns |  0.30 |    0.01 |      - |     - |     - |         - |\n| Dict_foreach                  | 1     |      13.23 ns |     0.221 ns |      0.185 ns |  0.33 |    0.01 |      - |     - |     - |         - |\n| ConcurrentDict_foreach        | 1     |     160.56 ns |     1.083 ns |      0.960 ns |  4.02 |    0.07 | 0.0100 |     - |     - |      64 B |\n| ImmutableDict_foreach         | 1     |     162.69 ns |     2.671 ns |      2.367 ns |  4.08 |    0.09 |      - |     - |     - |         - |\n|                               |       |               |              |               |       |         |        |       |       |           |\n| V4_HashMap_foreach            | 10    |     153.45 ns |     0.997 ns |      0.884 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V4_PartitionedHashMap_foreach | 10    |     404.07 ns |     3.534 ns |      3.133 ns |  2.63 |    0.02 |      - |     - |     - |         - |\n| V2_ImMap_Enumerate            | 10    |     122.57 ns |     2.177 ns |      1.700 ns |  0.80 |    0.01 | 0.0176 |     - |     - |     112 B |\n| DictSlim_foreach              | 10    |      53.15 ns |     0.771 ns |      0.721 ns |  0.35 |    0.01 |      - |     - |     - |         - |\n| Dict_foreach                  | 10    |      51.03 ns |     0.977 ns |      0.816 ns |  0.33 |    0.01 |      - |     - |     - |         - |\n| ConcurrentDict_foreach        | 10    |     282.17 ns |     4.126 ns |      3.860 ns |  1.84 |    0.03 | 0.0100 |     - |     - |      64 B |\n| ImmutableDict_foreach         | 10    |     554.93 ns |     7.623 ns |      6.758 ns |  3.62 |    0.05 |      - |     - |     - |         - |\n|                               |       |               |              |               |       |         |        |       |       |           |\n| V4_HashMap_foreach            | 100   |   1,620.36 ns |    15.329 ns |     12.801 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V4_PartitionedHashMap_foreach | 100   |   1,966.77 ns |    26.880 ns |     25.144 ns |  1.21 |    0.02 |      - |     - |     - |         - |\n| V2_ImMap_Enumerate            | 100   |   1,148.46 ns |    12.437 ns |     11.025 ns |  0.71 |    0.01 | 0.0210 |     - |     - |     136 B |\n| DictSlim_foreach              | 100   |     529.39 ns |     5.573 ns |      4.940 ns |  0.33 |    0.00 |      - |     - |     - |         - |\n| Dict_foreach                  | 100   |     494.13 ns |     9.209 ns |      8.614 ns |  0.31 |    0.01 |      - |     - |     - |         - |\n| ConcurrentDict_foreach        | 100   |   2,370.15 ns |    33.237 ns |     31.090 ns |  1.46 |    0.02 | 0.0076 |     - |     - |      64 B |\n| ImmutableDict_foreach         | 100   |   4,524.35 ns |    40.547 ns |     33.858 ns |  2.79 |    0.03 |      - |     - |     - |         - |\n|                               |       |               |              |               |       |         |        |       |       |           |\n| V4_HashMap_foreach            | 1000  |  17,206.01 ns |   152.714 ns |    135.377 ns |  1.00 |    0.00 |      - |     - |     - |         - |\n| V4_PartitionedHashMap_foreach | 1000  |  21,030.80 ns |   325.220 ns |    288.299 ns |  1.22 |    0.02 |      - |     - |     - |         - |\n| V2_ImMap_Enumerate            | 1000  |  12,200.97 ns |   173.829 ns |    162.600 ns |  0.71 |    0.01 | 0.0153 |     - |     - |     160 B |\n| DictSlim_foreach              | 1000  |   4,913.65 ns |    76.788 ns |     71.827 ns |  0.29 |    0.00 |      - |     - |     - |         - |\n| Dict_foreach                  | 1000  |   4,963.77 ns |    69.813 ns |     65.303 ns |  0.29 |    0.00 |      - |     - |     - |         - |\n| ConcurrentDict_foreach        | 1000  |  21,569.87 ns |   162.467 ns |    144.023 ns |  1.25 |    0.01 |      - |     - |     - |      64 B |\n| ImmutableDict_foreach         | 1000  |  47,263.06 ns |   907.028 ns |    804.057 ns |  2.75 |    0.05 |      - |     - |     - |         - |\n|                               |       |               |              |               |       |         |        |       |       |           |\n| V4_HashMap_foreach            | 10000 | 182,837.99 ns | 2,052.717 ns |  1,819.680 ns |  1.00 |    0.00 |      - |     - |     - |     176 B |\n| V4_PartitionedHashMap_foreach | 10000 | 232,269.89 ns | 2,514.057 ns |  2,099.352 ns |  1.27 |    0.02 |      - |     - |     - |         - |\n| V2_ImMap_Enumerate            | 10000 | 138,194.71 ns | 1,605.065 ns |  1,340.302 ns |  0.76 |    0.01 |      - |     - |     - |     192 B |\n| DictSlim_foreach              | 10000 |  49,479.00 ns |   937.417 ns |  1,003.025 ns |  0.27 |    0.00 |      - |     - |     - |         - |\n| Dict_foreach                  | 10000 |  46,780.99 ns |   380.189 ns |    355.629 ns |  0.26 |    0.00 |      - |     - |     - |         - |\n| ConcurrentDict_foreach        | 10000 | 194,166.07 ns |   919.960 ns |    860.531 ns |  1.06 |    0.01 |      - |     - |     - |      64 B |\n| ImmutableDict_foreach         | 10000 | 507,513.23 ns | 9,995.314 ns | 12,640.872 ns |  2.80 |    0.07 |      - |     - |     - |       1 B |\n```\n\n## End-to-end Example\n\nLet's assume you are implementing yet another DI container because why not :-)\n\nContainer should contain registry of `Type` to `Factory` mappings. \nOn resolution `Factory` is compiled to the delegate which you would like to cache, because compilation is costly. \nThe cache will store the mappings from `Type` to `Func\u003cobject\u003e`.\n\n__The requirements:__\n\n- The container may be used in parallel from different threads including registrations and resolutions. \n- The container state should not be corrupted and the cache should correspond to the current state of registrations.\n\nLet's design the basic container structure to support the requirements and __without locking__:\n\n```cs\n    public class Container\n    {\n        private readonly Ref\u003cRegistry\u003e _registry = Ref.Of(new Registry());\n\n        public void Register\u003cTService, TImpl\u003e() where TImpl : TService, new()\n        {\n            _registry.Swap(reg =\u003e reg.With(typeof(TService), new Factory(typeof(TImpl))));\n        }\n\n        public object Resolve\u003cTService\u003e()\n        {\n            return (TService)(_registry.Value.Resolve(typeof(TService)) ?? ThrowUnableToResolve(typeof(TService)));\n        }\n        \n        public object ThrowUnableToResolve(Type t) { throw new InvalidOperationException(\"Unable to resolve: \" + t); }\n\n        class Registry \n        {\n            ImHashMap\u003cType, Factory\u003e _registrations = ImHashMap\u003cType, Factory\u003e.Empty;\n            Ref\u003cImHashMap\u003cType, Func\u003cobject\u003e\u003e\u003e _resolutionCache = Ref.Of(ImHashMap\u003cType, Func\u003cobject\u003e\u003e.Empty);\n\n            // Creating a new registry with +1 registration and new reference to cache value\n            public Registry With(Type serviceType, Factory implFactory)\n            {\n                return new Registry() \n                {\t\n                    _registrations = _registrations.AddOrUpdate(serviceType, implFactory),\n                        \n                    // Here is most interesting part:\n                    // We are creating new independent reference pointing to cache value,\n                    // isolating it from possible parallel resolutions, \n                    // which will swap older version/ref of cache and won't touch the new one.\n                    _resolutionCache = Ref.Of(_resolutionCache.Value)\n                };\n            }\n\n            public object Resolve(Type serviceType)\n            {\n                var func = _resolutionCache.Value.GetValueOrDefault(serviceType);\n                if (func != null)\n                    return func();\n\n                var reg = _registrations.GetValueOrDefault(serviceType);\n                if (reg == null)\n                    return null;\n                \n                func = reg.CompileDelegate();\n                _resolutionCache.Swap(cache =\u003e cache.AddOrUpdate(serviceType, func));\n                return func.Invoke();\n            }\n        }\n        \n        class Factory \n        {\n            public readonly Type ImplType;\n            public Factory(Type implType) { ImplType = implType; }\n            public Func\u003cobject\u003e CompileDelegate() { return () =\u003e Activator.CreateInstance(ImplType); }\n        } \n    }\n```\n","funding_links":["https://github.com/sponsors/dadhi"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdadhi%2Fimtools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdadhi%2Fimtools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdadhi%2Fimtools/lists"}