-
Notifications
You must be signed in to change notification settings - Fork 879
Optimize sorting by leveraging ArrayPool for reduced allocations in ParameterCollection. #4331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
af0e476
7f37c49
cab16ad
51fbccc
ccccd7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
|
|
||
| { | ||
| "core": { | ||
| "changeLogMessages": [ | ||
| "Optimize ParameterCollection sorting by leveraging ArrayPool for reduced allocations. " | ||
| ], | ||
| "type": "patch", | ||
| "updateMinimum": false | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| /* | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
|
@@ -13,6 +13,7 @@ | |
| * permissions and limitations under the License. | ||
| */ | ||
| using System; | ||
| using System.Buffers; | ||
| using System.Collections.Generic; | ||
| using System.Globalization; | ||
| using System.IO; | ||
|
|
@@ -90,21 +91,43 @@ internal IEnumerable<KeyValuePair<string, string>> GetParametersEnumerable() | |
| yield return new KeyValuePair<string, string>(name, stringParameterValue.Value); | ||
| break; | ||
| case StringListParameterValue stringListParameterValue: | ||
| var sortedStringListParameterValue = stringListParameterValue.Value; | ||
| sortedStringListParameterValue.Sort(StringComparer.Ordinal); | ||
| foreach (var listValue in sortedStringListParameterValue) | ||
| yield return new KeyValuePair<string, string>(name, listValue); | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked the values of the parameters dictionary for the reproduction code provided in #1922 and none of them are
All of them are
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overall when I did the small improvements here in the past I deliberately left out any redesigns. The entire parameter valua collection being mutable would be one thing to look at besides others. Judging by the benchmark I ran this seems still giving good allocation gains that benefit's all SDK clients that run through this path I'd say it is worth and safe to keep. |
||
| var stringList = stringListParameterValue.Value; | ||
| var stringArray = ArrayPool<string>.Shared.Rent(stringList.Count); | ||
| try | ||
| { | ||
| stringList.CopyTo(stringArray); | ||
| Array.Sort(stringArray, 0, stringList.Count, StringComparer.Ordinal); | ||
| for (int i = 0; i < stringList.Count; i++) | ||
| yield return new KeyValuePair<string, string>(name, stringArray[i]); | ||
| } | ||
| finally | ||
| { | ||
| ArrayPool<string>.Shared.Return(stringArray); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Safer to clear?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
Comment on lines
+94
to
+107
|
||
| break; | ||
| } | ||
| case DoubleListParameterValue doubleListParameterValue: | ||
| var sortedDoubleListParameterValue = doubleListParameterValue.Value; | ||
| sortedDoubleListParameterValue.Sort(); | ||
| foreach (var listValue in sortedDoubleListParameterValue) | ||
| yield return new KeyValuePair<string, string>(name, listValue.ToString(CultureInfo.InvariantCulture)); | ||
| { | ||
| var doubleList = doubleListParameterValue.Value; | ||
| var doubleArray = ArrayPool<double>.Shared.Rent(doubleList.Count); | ||
| try | ||
| { | ||
| doubleList.CopyTo(doubleArray); | ||
| Array.Sort(doubleArray, 0, doubleList.Count); | ||
| for (int i = 0; i < doubleList.Count; i++) | ||
| yield return new KeyValuePair<string, string>(name, doubleArray[i].ToString(CultureInfo.InvariantCulture)); | ||
| } | ||
| finally | ||
| { | ||
| ArrayPool<double>.Shared.Return(doubleArray); | ||
| } | ||
| break; | ||
| } | ||
| default: | ||
| throw new AmazonClientException("Unsupported parameter value type '" + value.GetType().FullName + "'"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,31 @@ public void GetParametersAsString() | |
| Assert.Equal("key1=value1&key2=value2&key3=value3&key3=value4&key4=1.1&key4=2.1", parametersString); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void GetParametersAsString_ProducesCorrectlySortedOutput() | ||
| { | ||
| var parameters = new ParameterCollection | ||
| { | ||
| { "key3", "value3" }, | ||
| { "key1", "value1" }, | ||
| { "key2", "value2" }, | ||
| }; | ||
|
|
||
| var result = AWSSDKUtils.GetParametersAsString(parameters); | ||
| Assert.Equal("key1=value1&key2=value2&key3=value3", result); | ||
| } | ||
|
peterrsongg marked this conversation as resolved.
|
||
| [Fact] | ||
| public void GetParametersAsStringWithStringListParameterValueCorrectlySortsOutput() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like this test because it’s too tied to the current implementation and doesn’t check for the intended behavior. |
||
| { | ||
| var parameters = new ParameterCollection | ||
| { | ||
| {"key4", new List<string> { "value5", "value4" } }, | ||
| {"key1", new List<string>{"value1", "value2"} } | ||
| }; | ||
| var result = AWSSDKUtils.GetParametersAsString(parameters); | ||
| Assert.Equal("key1=value1&key1=value2&key4=value4&key4=value5", result); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToHexUppercase() | ||
| { | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR modifies Core SDK code but does not include a DevConfig file, which is required per CONTRIBUTING.md for all code changes. Since this is a bug fix (preventing in-place mutation of the original lists), a DevConfig file with a
"core"section and"type": "patch"should be added undergenerator/.DevConfigs/.