Last active
September 25, 2025 22:29
-
-
Save daiplusplus/72aa75dbb3d7b1cd6746c79a60e0e3f1 to your computer and use it in GitHub Desktop.
Dictionary<K,V> vs IReadOnlyDictionary<K,V>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using BenchmarkDotNet.Running; | |
| using BenchmarkDotNet.Attributes; | |
| using BenchmarkDotNet.Reports; | |
| namespace DictInterBench; | |
| public static class Program | |
| { | |
| public static readonly Object?[] CommonN = new Object?[] { 16, 128/*, 1024, 4096*/ }; | |
| public static void Main() | |
| { | |
| Summary summary = BenchmarkRunner.Run<BothDictionaryBenchmarks>(); | |
| // summary.Dump(); | |
| } | |
| /* | |
| Notes: | |
| - Both scenarios share the same Dictionary instance; the difference is interface vs concrete dispatch and any related JIT inlining effects. | |
| - Only read operations are benchmarked because IReadOnlyDictionary<T> doesn’t expose mutating APIs. | |
| - MemoryDiagnoser is enabled to observe allocation (should be zero for these operations). | |
| */ | |
| } | |
| //[MemoryDiagnoser] // we don't care about memory usage | |
| [SimpleJob] // default job; LINQPad will run it fine | |
| //[JsonExporterAttribute.FullCompressed( )] | |
| //[JsonExporterAttribute( fileNameSuffix: "DictionaryBenchmarks.json", indentJson: true, excludeMeasurements: false )] | |
| [CsvExporter] | |
| [CsvMeasurementsExporter] | |
| public class BothDictionaryBenchmarks | |
| { | |
| // Vary the dictionary size to see scaling and dispatch overhead behavior | |
| [Params( | |
| 16, | |
| 128//, | |
| // 1024//, | |
| // 4096 | |
| )] | |
| public Int32 N; | |
| private Dictionary <String,Object?> dict; | |
| private IReadOnlyDictionary<String,Object?> roDict; | |
| private String _hitKey; | |
| private String _missKey; | |
| [GlobalSetup] | |
| public void Setup() | |
| { | |
| this.dict = new Dictionary<String, Object?>( this.N, StringComparer.Ordinal); | |
| for ( Int32 i = 0; i < this.N; i++) | |
| { | |
| // deterministic keys | |
| this.dict.Add($"k{i:D6}", i); // store boxed ints | |
| } | |
| this.roDict = this.dict; // same instance, referenced via the interface | |
| // choose a key that exists and one that does not | |
| this._hitKey = $"k{( this.N / 2):D6}"; | |
| this._missKey = $"missing_{this.N}"; | |
| } | |
| // ----- IReadOnlyDictionary<T> ----- | |
| [Benchmark] | |
| public Object? IReadOnly_TryGetValue_Hit() | |
| { | |
| _ = this.roDict.TryGetValue( this._hitKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? IReadOnly_TryGetValue_Miss() | |
| { | |
| _ = this.roDict.TryGetValue( this._missKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? IReadOnly_Indexer_Hit() | |
| { | |
| return this.roDict[this._hitKey]; | |
| } | |
| [Benchmark] | |
| public Boolean IReadOnly_ContainsKey_Hit() | |
| { | |
| return this.roDict.ContainsKey( this._hitKey ); | |
| } | |
| [Benchmark] | |
| public Int32 IReadOnly_Enumerate_All() | |
| { | |
| Int32 count = 0; | |
| foreach( KeyValuePair<String, Object?> kvp in this.roDict ) | |
| { | |
| if( kvp.Value is not null ) count++; | |
| } | |
| return count; | |
| } | |
| // ----- Dictionary<T> (concrete) ----- | |
| [Benchmark] | |
| public Object? Dict_TryGetValue_Hit() | |
| { | |
| _ = this.dict.TryGetValue( this._hitKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? Dict_TryGetValue_Miss() | |
| { | |
| _ = this.dict.TryGetValue( this._missKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? Dict_Indexer_Hit() | |
| { | |
| return this.dict[this._hitKey]; | |
| } | |
| [Benchmark] | |
| public Boolean Dict_ContainsKey_Hit() | |
| { | |
| return this.dict.ContainsKey( this._hitKey ); | |
| } | |
| [Benchmark] | |
| public Int32 Dict_Enumerate_All() | |
| { | |
| Int32 count = 0; | |
| foreach ( KeyValuePair<String, Object?> kvp in this.dict ) | |
| { | |
| if (kvp.Value is not null) count++; | |
| } | |
| return count; | |
| } | |
| } | |
| [SimpleJob] | |
| [CsvExporter] | |
| [CsvMeasurementsExporter] | |
| public class IReadOnlyDictionaryBenchmarks | |
| { | |
| [Params( new Object?[] { 16, 128, 1024 /*, 4096*/ } )] | |
| public Int32 N; | |
| private IReadOnlyDictionary<String,Object?> roDict; | |
| private String hitKey; | |
| private String missKey; | |
| [GlobalSetup] | |
| public void Setup() | |
| { | |
| Dictionary<String,Object?> dict = new Dictionary<String,Object?>( capacity: this.N, comparer: StringComparer.Ordinal ); | |
| for ( Int32 i = 0; i < this.N; i++) | |
| { | |
| // deterministic keys | |
| dict.Add( $"k{i:D6}", i ); // store boxed ints | |
| } | |
| this.roDict = dict; // same instance, referenced via the interface | |
| // choose a key that exists and one that does not | |
| this.hitKey = $"k{( this.N / 2):D6}"; | |
| this.missKey = $"missing_{this.N}"; | |
| } | |
| [Benchmark] | |
| public Object? TryGetValue_Hit() | |
| { | |
| _ = this.roDict.TryGetValue( this.hitKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? TryGetValue_Miss() | |
| { | |
| _ = this.roDict.TryGetValue( this.missKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? Indexer_Hit() | |
| { | |
| return this.roDict[this.hitKey]; | |
| } | |
| [Benchmark] | |
| public Boolean ContainsKey_Hit() | |
| { | |
| return this.roDict.ContainsKey( this.hitKey ); | |
| } | |
| [Benchmark] | |
| public Int32 Enumerate_All() | |
| { | |
| Int32 count = 0; | |
| foreach( KeyValuePair<String, Object?> kvp in this.roDict ) | |
| { | |
| if( kvp.Value is not null ) count++; | |
| } | |
| return count; | |
| } | |
| } | |
| [SimpleJob] | |
| [CsvExporter] | |
| [CsvMeasurementsExporter] | |
| public class ClassDictionaryBenchmarks | |
| { | |
| [Params( new Object?[] { 16, 128, 1024 /*, 4096*/ } )] | |
| public Int32 N; | |
| private Dictionary<String,Object?> dict; | |
| private String hitKey; | |
| private String missKey; | |
| [GlobalSetup] | |
| public void Setup() | |
| { | |
| this.dict = new Dictionary<String,Object?>( capacity: this.N, comparer: StringComparer.Ordinal ); | |
| for ( Int32 i = 0; i < this.N; i++) | |
| { | |
| // deterministic keys | |
| this.dict.Add( $"k{i:D6}", i ); // store boxed ints | |
| } | |
| // choose a key that exists and one that does not | |
| this.hitKey = $"k{( this.N / 2):D6}"; | |
| this.missKey = $"missing_{this.N}"; | |
| } | |
| [Benchmark] | |
| public Object? TryGetValue_Hit() | |
| { | |
| _ = this.dict.TryGetValue( this.hitKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? TryGetValue_Miss() | |
| { | |
| _ = this.dict.TryGetValue( this.missKey, out Object? v ); | |
| return v; | |
| } | |
| [Benchmark] | |
| public Object? Indexer_Hit() | |
| { | |
| return this.dict[this.hitKey]; | |
| } | |
| [Benchmark] | |
| public Boolean ContainsKey_Hit() | |
| { | |
| return this.dict.ContainsKey( this.hitKey ); | |
| } | |
| [Benchmark] | |
| public Int32 Enumerate_All() | |
| { | |
| Int32 count = 0; | |
| foreach ( KeyValuePair<String, Object?> kvp in this.dict ) | |
| { | |
| if (kvp.Value is not null) count++; | |
| } | |
| return count; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| net48 | net6.0 | net8.0 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Method | N | Mean | Error | StdDev | Mean | Error | StdDev | Mean | Error | StdDev | |
| Dict_ContainsKey_Hit | 16 | 20.27 | 0.43 | 0.753 | 14.713 | 0.3133 | 0.4877 | 13.114 | 0.2898 | 0.2711 | |
| Dict_ContainsKey_Hit | 128 | 17.96 | 0.363 | 0.485 | 11.532 | 0.2509 | 0.3262 | 12.604 | 0.2798 | 0.333 | |
| Dict_Enumerate_All | 16 | 90 | 1.773 | 2.76 | 83.452 | 1.6642 | 2.333 | 14.668 | 0.3219 | 0.6354 | |
| Dict_Enumerate_All | 128 | 566.91 | 11.265 | 18.822 | 577.78 | 11.2449 | 12.0319 | 126.604 | 2.3813 | 3.9125 | |
| Dict_Indexer_Hit | 16 | 19.65 | 0.448 | 0.748 | 14.634 | 0.3226 | 0.4828 | 13.742 | 0.3144 | 0.2941 | |
| Dict_Indexer_Hit | 128 | 17.86 | 0.404 | 0.686 | 11.587 | 0.2717 | 0.2269 | 10.98 | 0.2141 | 0.2103 | |
| Dict_TryGetValue_Hit | 16 | 20.9 | 0.47 | 0.643 | 15.571 | 0.3478 | 0.3866 | 12.944 | 0.3071 | 0.3993 | |
| Dict_TryGetValue_Hit | 128 | 19.85 | 0.409 | 0.502 | 12.811 | 0.3093 | 0.5335 | 11.44 | 0.264 | 0.5511 | |
| Dict_TryGetValue_Miss | 16 | 11.79 | 0.287 | 0.268 | 11.124 | 0.2663 | 0.3368 | 8.135 | 0.1853 | 0.206 | |
| Dict_TryGetValue_Miss | 128 | 12.44 | 0.258 | 0.229 | 9.024 | 0.2307 | 0.2369 | 6.504 | 0.1818 | 0.2777 | |
| IReadOnly_ContainsKey_Hit | 16 | 20.89 | 0.435 | 0.762 | 15.868 | 0.2705 | 0.2398 | 13.944 | 0.3001 | 0.4107 | |
| IReadOnly_ContainsKey_Hit | 128 | 18.5 | 0.33 | 0.292 | 15.843 | 0.3034 | 0.2838 | 11.365 | 0.2478 | 0.2069 | |
| IReadOnly_Enumerate_All | 16 | 210.96 | 3.776 | 3.154 | 212.092 | 2.8244 | 2.642 | 219.806 | 1.1967 | 1.0608 | |
| IReadOnly_Enumerate_All | 128 | 1,467.53 | 29.111 | 34.654 | 1,473.21 | 28.0964 | 28.8529 | 1,666.04 | 4.8648 | 4.0623 | |
| IReadOnly_Indexer_Hit | 16 | 20.13 | 0.438 | 0.755 | 14.993 | 0.3524 | 0.4456 | 13.559 | 0.2659 | 0.2357 | |
| IReadOnly_Indexer_Hit | 128 | 18.35 | 0.379 | 0.674 | 12.159 | 0.2932 | 0.411 | 11.527 | 0.2837 | 0.3977 | |
| IReadOnly_TryGetValue_Hit | 16 | 21.13 | 0.476 | 0.619 | 15.774 | 0.3626 | 0.5752 | 14.31 | 0.3387 | 0.4636 | |
| IReadOnly_TryGetValue_Hit | 128 | 20.07 | 0.445 | 0.609 | 13.184 | 0.3082 | 0.432 | 11.548 | 0.2854 | 0.3398 | |
| IReadOnly_TryGetValue_Miss | 16 | 12.68 | 0.266 | 0.473 | 11.035 | 0.25 | 0.2568 | 8.526 | 0.2216 | 0.2552 | |
| IReadOnly_TryGetValue_Miss | 128 | 12.96 | 0.302 | 0.336 | 9.468 | 0.2417 | 0.3466 | 7.34 | 0.2004 | 0.2675 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Method | Job | AnalyzeLaunchVariance | EvaluateOverhead | MaxAbsoluteError | MaxRelativeError | MinInvokeCount | MinIterationTime | OutlierMode | Affinity | EnvironmentVariables | Jit | LargeAddressAware | Platform | PowerPlanMode | Runtime | AllowVeryLargeObjects | Concurrent | CpuGroups | Force | HeapAffinitizeMask | HeapCount | NoAffinitize | RetainVm | Server | Arguments | BuildConfiguration | Clock | EngineFactory | NuGetReferences | Toolchain | IsMutator | InvocationCount | IterationCount | IterationTime | LaunchCount | MaxIterationCount | MaxWarmupIterationCount | MemoryRandomization | MinIterationCount | MinWarmupIterationCount | RunStrategy | UnrollFactor | WarmupCount | N | Mean | Error | StdDev | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 21.13 ns | 0.476 ns | 0.619 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 12.68 ns | 0.266 ns | 0.473 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 20.13 ns | 0.438 ns | 0.755 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 20.89 ns | 0.435 ns | 0.762 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 210.96 ns | 3.776 ns | 3.154 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 20.90 ns | 0.470 ns | 0.643 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 11.79 ns | 0.287 ns | 0.268 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 19.65 ns | 0.448 ns | 0.748 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 20.27 ns | 0.430 ns | 0.753 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 90.00 ns | 1.773 ns | 2.760 ns | |
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 20.07 ns | 0.445 ns | 0.609 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 12.96 ns | 0.302 ns | 0.336 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 18.35 ns | 0.379 ns | 0.674 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 18.50 ns | 0.330 ns | 0.292 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 1,467.53 ns | 29.111 ns | 34.654 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 19.85 ns | 0.409 ns | 0.502 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 12.44 ns | 0.258 ns | 0.229 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 17.86 ns | 0.404 ns | 0.686 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 17.96 ns | 0.363 ns | 0.485 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET Framework 4.8.1 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 566.91 ns | 11.265 ns | 18.822 ns |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Method | Job | AnalyzeLaunchVariance | EvaluateOverhead | MaxAbsoluteError | MaxRelativeError | MinInvokeCount | MinIterationTime | OutlierMode | Affinity | EnvironmentVariables | Jit | LargeAddressAware | Platform | PowerPlanMode | Runtime | AllowVeryLargeObjects | Concurrent | CpuGroups | Force | HeapAffinitizeMask | HeapCount | NoAffinitize | RetainVm | Server | Arguments | BuildConfiguration | Clock | EngineFactory | NuGetReferences | Toolchain | IsMutator | InvocationCount | IterationCount | IterationTime | LaunchCount | MaxIterationCount | MaxWarmupIterationCount | MemoryRandomization | MinIterationCount | MinWarmupIterationCount | RunStrategy | UnrollFactor | WarmupCount | N | Mean | Error | StdDev | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 15.774 ns | 0.3626 ns | 0.5752 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 11.035 ns | 0.2500 ns | 0.2568 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 14.993 ns | 0.3524 ns | 0.4456 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 15.868 ns | 0.2705 ns | 0.2398 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 212.092 ns | 2.8244 ns | 2.6420 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 15.571 ns | 0.3478 ns | 0.3866 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 11.124 ns | 0.2663 ns | 0.3368 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 14.634 ns | 0.3226 ns | 0.4828 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 14.713 ns | 0.3133 ns | 0.4877 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 83.452 ns | 1.6642 ns | 2.3330 ns | |
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 13.184 ns | 0.3082 ns | 0.4320 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 9.468 ns | 0.2417 ns | 0.3466 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 12.159 ns | 0.2932 ns | 0.4110 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 15.843 ns | 0.3034 ns | 0.2838 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 1,473.212 ns | 28.0964 ns | 28.8529 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 12.811 ns | 0.3093 ns | 0.5335 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 9.024 ns | 0.2307 ns | 0.2369 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.587 ns | 0.2717 ns | 0.2269 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.532 ns | 0.2509 ns | 0.3262 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 6.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 577.780 ns | 11.2449 ns | 12.0319 ns |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Method | Job | AnalyzeLaunchVariance | EvaluateOverhead | MaxAbsoluteError | MaxRelativeError | MinInvokeCount | MinIterationTime | OutlierMode | Affinity | EnvironmentVariables | Jit | LargeAddressAware | Platform | PowerPlanMode | Runtime | AllowVeryLargeObjects | Concurrent | CpuGroups | Force | HeapAffinitizeMask | HeapCount | NoAffinitize | RetainVm | Server | Arguments | BuildConfiguration | Clock | EngineFactory | NuGetReferences | Toolchain | IsMutator | InvocationCount | IterationCount | IterationTime | LaunchCount | MaxIterationCount | MaxWarmupIterationCount | MemoryRandomization | MinIterationCount | MinWarmupIterationCount | RunStrategy | UnrollFactor | WarmupCount | N | Mean | Error | StdDev | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 14.310 ns | 0.3387 ns | 0.4636 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 8.526 ns | 0.2216 ns | 0.2552 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 13.559 ns | 0.2659 ns | 0.2357 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 13.944 ns | 0.3001 ns | 0.4107 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 219.806 ns | 1.1967 ns | 1.0608 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 12.944 ns | 0.3071 ns | 0.3993 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 8.135 ns | 0.1853 ns | 0.2060 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 13.742 ns | 0.3144 ns | 0.2941 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 13.114 ns | 0.2898 ns | 0.2711 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 16 | 14.668 ns | 0.3219 ns | 0.6354 ns | |
| IReadOnly_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.548 ns | 0.2854 ns | 0.3398 ns | |
| IReadOnly_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 7.340 ns | 0.2004 ns | 0.2675 ns | |
| IReadOnly_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.527 ns | 0.2837 ns | 0.3977 ns | |
| IReadOnly_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.365 ns | 0.2478 ns | 0.2069 ns | |
| IReadOnly_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 1,666.039 ns | 4.8648 ns | 4.0623 ns | |
| Dict_TryGetValue_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 11.440 ns | 0.2640 ns | 0.5511 ns | |
| Dict_TryGetValue_Miss | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 6.504 ns | 0.1818 ns | 0.2777 ns | |
| Dict_Indexer_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 10.980 ns | 0.2141 ns | 0.2103 ns | |
| Dict_ContainsKey_Hit | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 12.604 ns | 0.2798 ns | 0.3330 ns | |
| Dict_Enumerate_All | DefaultJob | False | Default | Default | Default | Default | Default | Default | 1111111111111111 | Empty | RyuJit | Default | X64 | 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c | .NET 8.0 | False | True | False | True | Default | Default | False | False | False | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | Default | 16 | Default | 128 | 126.604 ns | 2.3813 ns | 3.9125 ns |
Author
daiplusplus
commented
Sep 25, 2025
Author
Some thoughts for possible future revisions:
- Problem: The
Enumerate_Allmethods only invokeDictionary<K,V>.GetEnumerator()(orIReadOnlyDictionary<K,V>.GetEnumerator()once - but then make hundreds+ of calls to either the nonvirtualstruct Dictionary<K,V>.Enumerator.MoveNext()method - or the virtualIEnumerator<Kvp<K,V>>.MoveNext()method.- We'd need a new extension-method:
IReadOnlyDictionary.TryGetValueTypeEnumerator()- and then it starts getting too silly.
- We'd need a new extension-method:
- Idea: Add a 3rd mode: a
readonly struct ReadOnlyDictionary<K,V>wrapper struct which would allow for exposing only read-only members to consumers while avoiding indirection and vtable calls through anyinterfacetype. - Idea: Add a 4th mode: adapt methods to use interface, but as generic-type constraints (i.e. like Swift
protocoltypes) used withstructwrappers for zero-virtual-call code-paths - at the cost of hideous amounts of hair-pulling.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment