Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

stephentoub
Copy link
Member

It's reasonably common to construct a dictionary from a KeyValuePair<TKey, TValue>[] or a List<KeyValuePair<TKey, TValue>>, and we can make both cheaper. We can also unwrap a Dictionary wrapped in a ReadOnlyDictionary in order to better utliize the existing optimizations around Dictionary.

Method Toolchain Length Mean Ratio Allocated Alloc Ratio
FromArray \main\corerun.exe 1 60.18 ns 1.00 224 B 1.00
FromArray \pr\corerun.exe 1 45.21 ns 0.75 192 B 0.86
FromList \main\corerun.exe 1 66.58 ns 1.00 232 B 1.00
FromList \pr\corerun.exe 1 46.90 ns 0.70 192 B 0.83
FromOther \main\corerun.exe 1 67.22 ns 1.00 240 B 1.00
FromOther \pr\corerun.exe 1 72.64 ns 1.07 240 B 1.00
FromReadOnlyDictionary \main\corerun.exe 1 70.60 ns 1.00 240 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 1 45.04 ns 0.64 192 B 0.80
FromArray \main\corerun.exe 10 161.57 ns 1.00 384 B 1.00
FromArray \pr\corerun.exe 10 123.19 ns 0.75 352 B 0.92
FromList \main\corerun.exe 10 194.36 ns 1.00 392 B 1.00
FromList \pr\corerun.exe 10 118.41 ns 0.61 352 B 0.90
FromOther \main\corerun.exe 10 282.64 ns 1.00 824 B 1.00
FromOther \pr\corerun.exe 10 281.12 ns 0.98 824 B 1.00
FromReadOnlyDictionary \main\corerun.exe 10 218.75 ns 1.00 400 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 10 78.69 ns 0.36 352 B 0.88
FromArray \main\corerun.exe 100 1,068.79 ns 1.00 2304 B 1.00
FromArray \pr\corerun.exe 100 764.88 ns 0.71 2272 B 0.99
FromList \main\corerun.exe 100 1,365.59 ns 1.00 2312 B 1.00
FromList \pr\corerun.exe 100 834.13 ns 0.61 2272 B 0.98
FromOther \main\corerun.exe 100 2,122.52 ns 1.00 7440 B 1.00
FromOther \pr\corerun.exe 100 2,136.31 ns 1.01 7440 B 1.00
FromReadOnlyDictionary \main\corerun.exe 100 1,660.43 ns 1.00 2320 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 100 421.00 ns 0.25 2272 B 0.98
FromArray \main\corerun.exe 1000 10,293.70 ns 1.00 22224 B 1.00
FromArray \pr\corerun.exe 1000 7,303.10 ns 0.71 22192 B 1.00
FromList \main\corerun.exe 1000 12,777.52 ns 1.00 22232 B 1.00
FromList \pr\corerun.exe 1000 7,868.13 ns 0.62 22192 B 1.00
FromOther \main\corerun.exe 1000 20,186.57 ns 1.00 73216 B 1.00
FromOther \pr\corerun.exe 1000 20,459.95 ns 1.01 73216 B 1.00
FromReadOnlyDictionary \main\corerun.exe 1000 16,134.17 ns 1.00 22240 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 1000 4,001.67 ns 0.25 22192 B 1.00
private KeyValuePair<int, int>[] _array;
private List<KeyValuePair<int, int>> _list;
private IEnumerable<KeyValuePair<int, int>> _other;
private ReadOnlyDictionary<int, int> _rod;

[Params(1, 10, 100, 1000)]
public int Length { get; set; }

[GlobalSetup]
public void Setup()
{
    _array = Enumerable.Range(0, Length).Select(i => new KeyValuePair<int, int>(i, i)).ToArray();
    _list = new List<KeyValuePair<int, int>>(_array);
    _other = _array.Select(kvp => kvp);
    _rod = new ReadOnlyDictionary<int, int>(_array.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
}

[Benchmark] public Dictionary<int, int> FromArray() => new Dictionary<int, int>(_array);
[Benchmark] public Dictionary<int, int> FromList() => new Dictionary<int, int>(_list);
[Benchmark] public Dictionary<int, int> FromOther() => new Dictionary<int, int>(_other);
[Benchmark] public Dictionary<int, int> FromReadOnlyDictionary() => new Dictionary<int, int>(_rod);

@stephentoub stephentoub added this to the 8.0.0 milestone May 15, 2023
@ghost ghost assigned stephentoub May 15, 2023
@ghost
Copy link

ghost commented May 15, 2023

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

Issue Details

It's reasonably common to construct a dictionary from a KeyValuePair<TKey, TValue>[] or a List<KeyValuePair<TKey, TValue>>, and we can make both cheaper. We can also unwrap a Dictionary wrapped in a ReadOnlyDictionary in order to better utliize the existing optimizations around Dictionary.

Method Toolchain Length Mean Ratio Allocated Alloc Ratio
FromArray \main\corerun.exe 1 60.18 ns 1.00 224 B 1.00
FromArray \pr\corerun.exe 1 45.21 ns 0.75 192 B 0.86
FromList \main\corerun.exe 1 66.58 ns 1.00 232 B 1.00
FromList \pr\corerun.exe 1 46.90 ns 0.70 192 B 0.83
FromOther \main\corerun.exe 1 67.22 ns 1.00 240 B 1.00
FromOther \pr\corerun.exe 1 72.64 ns 1.07 240 B 1.00
FromReadOnlyDictionary \main\corerun.exe 1 70.60 ns 1.00 240 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 1 45.04 ns 0.64 192 B 0.80
FromArray \main\corerun.exe 10 161.57 ns 1.00 384 B 1.00
FromArray \pr\corerun.exe 10 123.19 ns 0.75 352 B 0.92
FromList \main\corerun.exe 10 194.36 ns 1.00 392 B 1.00
FromList \pr\corerun.exe 10 118.41 ns 0.61 352 B 0.90
FromOther \main\corerun.exe 10 282.64 ns 1.00 824 B 1.00
FromOther \pr\corerun.exe 10 281.12 ns 0.98 824 B 1.00
FromReadOnlyDictionary \main\corerun.exe 10 218.75 ns 1.00 400 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 10 78.69 ns 0.36 352 B 0.88
FromArray \main\corerun.exe 100 1,068.79 ns 1.00 2304 B 1.00
FromArray \pr\corerun.exe 100 764.88 ns 0.71 2272 B 0.99
FromList \main\corerun.exe 100 1,365.59 ns 1.00 2312 B 1.00
FromList \pr\corerun.exe 100 834.13 ns 0.61 2272 B 0.98
FromOther \main\corerun.exe 100 2,122.52 ns 1.00 7440 B 1.00
FromOther \pr\corerun.exe 100 2,136.31 ns 1.01 7440 B 1.00
FromReadOnlyDictionary \main\corerun.exe 100 1,660.43 ns 1.00 2320 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 100 421.00 ns 0.25 2272 B 0.98
FromArray \main\corerun.exe 1000 10,293.70 ns 1.00 22224 B 1.00
FromArray \pr\corerun.exe 1000 7,303.10 ns 0.71 22192 B 1.00
FromList \main\corerun.exe 1000 12,777.52 ns 1.00 22232 B 1.00
FromList \pr\corerun.exe 1000 7,868.13 ns 0.62 22192 B 1.00
FromOther \main\corerun.exe 1000 20,186.57 ns 1.00 73216 B 1.00
FromOther \pr\corerun.exe 1000 20,459.95 ns 1.01 73216 B 1.00
FromReadOnlyDictionary \main\corerun.exe 1000 16,134.17 ns 1.00 22240 B 1.00
FromReadOnlyDictionary \pr\corerun.exe 1000 4,001.67 ns 0.25 22192 B 1.00
private KeyValuePair<int, int>[] _array;
private List<KeyValuePair<int, int>> _list;
private IEnumerable<KeyValuePair<int, int>> _other;
private ReadOnlyDictionary<int, int> _rod;

[Params(1, 10, 100, 1000)]
public int Length { get; set; }

[GlobalSetup]
public void Setup()
{
    _array = Enumerable.Range(0, Length).Select(i => new KeyValuePair<int, int>(i, i)).ToArray();
    _list = new List<KeyValuePair<int, int>>(_array);
    _other = _array.Select(kvp => kvp);
    _rod = new ReadOnlyDictionary<int, int>(_array.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
}

[Benchmark] public Dictionary<int, int> FromArray() => new Dictionary<int, int>(_array);
[Benchmark] public Dictionary<int, int> FromList() => new Dictionary<int, int>(_list);
[Benchmark] public Dictionary<int, int> FromOther() => new Dictionary<int, int>(_other);
[Benchmark] public Dictionary<int, int> FromReadOnlyDictionary() => new Dictionary<int, int>(_rod);
Author: stephentoub
Assignees: -
Labels:

area-System.Collections, tenet-performance

Milestone: 8.0.0

… ...) ctors

It's reasonably common to construct a dictionary from a `KeyValuePair<TKey, TValue>[]` or a `List<KeyValuePair<TKey, TValue>>`, and we can make both cheaper.  We can also unwrap a Dictionary wrapped in a ReadOnlyDictionary in order to better utliize the existing optimizations around Dictionary.
@stephentoub stephentoub merged commit 709444f into dotnet:main May 17, 2023
@stephentoub stephentoub deleted the dictionaryctor branch May 17, 2023 14:23
@ghost ghost locked as resolved and limited conversation to collaborators Jun 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants