From b01c8e124771e5d902b3693927c3ea400157e388 Mon Sep 17 00:00:00 2001 From: John Call Date: Mon, 14 Dec 2020 02:56:01 -0800 Subject: [PATCH] SortedDictionary Copy optimization (#45659) * Sorted Dictionary Copy optimization * Update src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs Co-authored-by: Jan Kotas * Feedback Co-authored-by: Jan Kotas --- .../Collections/Generic/SortedDictionary.cs | 19 ++++++++++++++++--- .../SortedDictionary.Generic.Tests.cs | 13 +++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs index cd352641e68a3..f9c3f1fcdfdf5 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs @@ -35,11 +35,22 @@ public SortedDictionary(IDictionary dictionary, IComparer? c throw new ArgumentNullException(nameof(dictionary)); } - _set = new TreeSet>(new KeyValuePairComparer(comparer)); + var keyValuePairComparer = new KeyValuePairComparer(comparer); - foreach (KeyValuePair pair in dictionary) + if (dictionary is SortedDictionary sortedDictionary && + sortedDictionary._set.Comparer is KeyValuePairComparer kv && + kv.keyComparer.Equals(keyValuePairComparer.keyComparer)) + { + _set = new TreeSet>(sortedDictionary._set, keyValuePairComparer); + } + else { - _set.Add(pair); + _set = new TreeSet>(keyValuePairComparer); + + foreach (KeyValuePair pair in dictionary) + { + _set.Add(pair); + } } } @@ -961,6 +972,8 @@ public TreeSet() public TreeSet(IComparer? comparer) : base(comparer) { } + internal TreeSet(TreeSet set, IComparer? comparer) : base(set, comparer) { } + private TreeSet(SerializationInfo siInfo, StreamingContext context) : base(siInfo, context) { } internal override bool AddIfNotPresent(T item) diff --git a/src/libraries/System.Collections/tests/Generic/SortedDictionary/SortedDictionary.Generic.Tests.cs b/src/libraries/System.Collections/tests/Generic/SortedDictionary/SortedDictionary.Generic.Tests.cs index 8d8761175b897..cac00bc6723b4 100644 --- a/src/libraries/System.Collections/tests/Generic/SortedDictionary/SortedDictionary.Generic.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/SortedDictionary/SortedDictionary.Generic.Tests.cs @@ -57,9 +57,18 @@ public void SortedDictionary_Generic_Constructor_IDictionary_IComparer(int count { IComparer comparer = GetKeyIComparer(); IDictionary source = GenericIDictionaryFactory(count); - SortedDictionary copied = new SortedDictionary(source, comparer); - Assert.Equal(source, copied); + SortedDictionary sourceSorted = new SortedDictionary(source, comparer); + Assert.Equal(source, sourceSorted); + Assert.Equal(comparer, sourceSorted.Comparer); + // Test copying a sorted dictionary. + SortedDictionary copied = new SortedDictionary(sourceSorted, comparer); + Assert.Equal(sourceSorted, copied); Assert.Equal(comparer, copied.Comparer); + // Test copying a sorted dictionary with a different comparer. + IComparer reverseComparer = Comparer.Create((key1, key2) => -comparer.Compare(key1, key2)); + SortedDictionary copiedReverse = new SortedDictionary(sourceSorted, reverseComparer); + Assert.Equal(sourceSorted, copiedReverse); + Assert.Equal(reverseComparer, copiedReverse.Comparer); } #endregion