From 2f0bb21afc19ee39df424a287d2f889506b03b32 Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:33:27 +0000 Subject: [PATCH] Replaced LINQ with iteration for performance improvements. --- .../Client.Class.ConvertToString.liquid | 13 ++++- .../Client.Class.PathParameter.liquid | 18 +++++-- .../Templates/Client.Class.liquid | 4 +- .../Templates/JsonExceptionConverter.liquid | 48 +++++++++++++------ ...ork=net7.0_generatesCode=True.verified.txt | 38 ++++++++++++--- .../GeneratedClientsCs.gen | 38 ++++++++++++--- src/NSwag.sln | 6 +++ src/NuGet.Config | 4 +- 8 files changed, 133 insertions(+), 36 deletions(-) diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.ConvertToString.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.ConvertToString.liquid index 08f426cfbd..4d52676038 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.ConvertToString.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.ConvertToString.liquid @@ -37,10 +37,19 @@ private string ConvertToString(object value, System.Globalization.CultureInfo cu { return System.Convert.ToBase64String((byte[]) value); } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } else if (value.GetType().IsArray) { - var array = System.Linq.Enumerable.OfType<object>((System.Array) value); - return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); + } + return string.Join(",", valueTextArray); } var result = System.Convert.ToString(value, cultureInfo); diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid index afbecb8a5e..7132ad9769 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid @@ -1,13 +1,25 @@ {% if parameter.IsDateTimeArray -%} -urlBuilder_.Append(System.Uri.EscapeDataString(string.Join(",", System.Linq.Enumerable.Select({{ parameter.VariableName }}, s_ => s_.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))))); +for (var i = 0; i < {{ parameter.VariableName }}.Length; i++) +{ + if (i > 0) urlBuilder_.Append(','); + urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}[i].ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))); +} {% elsif parameter.IsDateArray -%} -urlBuilder_.Append(System.Uri.EscapeDataString(string.Join(",", System.Linq.Enumerable.Select({{ parameter.VariableName }}, s_ => s_.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))))); +for (var i = 0; i < {{ parameter.VariableName }}.Length; i++) +{ + if (i > 0) urlBuilder_.Append(','); + urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}[i].ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))); +} {% elsif parameter.IsDateTime -%} urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))); {% elsif parameter.IsDate -%} urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))); {% elsif parameter.IsArray -%} -urlBuilder_.Append(System.Uri.EscapeDataString(string.Join(",", System.Linq.Enumerable.Select({{ parameter.VariableName }}, s_ => ConvertToString(s_, System.Globalization.CultureInfo.InvariantCulture))))); +for (var i = 0; i < {{ parameter.VariableName }}.Length; i++) +{ + if (i > 0) urlBuilder_.Append(','); + urlBuilder_.Append(ConvertToString({{ parameter.VariableName }}[i], System.Globalization.CultureInfo.InvariantCulture)); +} {% else -%} urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString({{ parameter.VariableName }}, System.Globalization.CultureInfo.InvariantCulture))); {%- endif %} diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid index 1666ea275b..8397ed8bef 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid @@ -333,7 +333,9 @@ var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/JsonExceptionConverter.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/JsonExceptionConverter.liquid index f0dfb80567..45942aafa3 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/JsonExceptionConverter.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/JsonExceptionConverter.liquid @@ -126,27 +126,47 @@ internal class JsonExceptionConverter : Newtonsoft.Json.JsonConverter private System.Collections.Generic.IDictionary<System.Reflection.PropertyInfo, string> GetExceptionProperties(System.Type exceptionType) { var result = new System.Collections.Generic.Dictionary<System.Reflection.PropertyInfo, string>(); - foreach (var property in System.Linq.Enumerable.Where(System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties(exceptionType), - p => p.GetMethod?.IsPublic == true)) + foreach (var property in System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties(exceptionType)) { + if (property.GetMethod?.IsPublic != true) + { + continue; + } + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute<Newtonsoft.Json.JsonPropertyAttribute>(property); var propertyName = attribute != null ? attribute.PropertyName : property.Name; - - if (!System.Linq.Enumerable.Contains(new[] { "Message", "StackTrace", "Source", "InnerException", "Data", "TargetSite", "HelpLink", "HResult" }, propertyName)) - result[property] = propertyName; + + switch (propertyName) + { + case "Message": + case "StackTrace": + case "Source": + case "InnerException": + case "Data": + case "TargetSite": + case "HelpLink": + case "HResult": + break; + default: + result[property] = propertyName; + break; + } } return result; } - private void SetExceptionFieldValue(Newtonsoft.Json.Linq.JObject jObject, string propertyName, object value, string fieldName, Newtonsoft.Json.Serialization.IContractResolver resolver, Newtonsoft.Json.JsonSerializer serializer) - { - var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(System.Exception)).GetDeclaredField(fieldName); - var jsonPropertyName = resolver is Newtonsoft.Json.Serialization.DefaultContractResolver ? ((Newtonsoft.Json.Serialization.DefaultContractResolver)resolver).GetResolvedPropertyName(propertyName) : propertyName; - var property = System.Linq.Enumerable.FirstOrDefault(jObject.Properties(), p => System.String.Equals(p.Name, jsonPropertyName, System.StringComparison.OrdinalIgnoreCase)); - if (property != null) + private void SetExceptionFieldValue(Newtonsoft.Json.Linq.JObject jObject, string propertyName, object value, string fieldName, Newtonsoft.Json.Serialization.IContractResolver resolver, Newtonsoft.Json.JsonSerializer serializer) { - var fieldValue = property.Value.ToObject(field.FieldType, serializer); - field.SetValue(value, fieldValue); + var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(System.Exception)).GetDeclaredField(fieldName); + var jsonPropertyName = resolver is Newtonsoft.Json.Serialization.DefaultContractResolver ? ((Newtonsoft.Json.Serialization.DefaultContractResolver)resolver).GetResolvedPropertyName(propertyName) : propertyName; + foreach (var property in jObject.Properties()) + { + if (System.String.Equals(p.Name, jsonPropertyName, System.StringComparison.OrdinalIgnoreCase)) + { + var fieldValue = property.Value.ToObject(field.FieldType, serializer); + field.SetValue(value, fieldValue); + break; + } + } } } -} \ No newline at end of file diff --git a/src/NSwag.ConsoleCore.Tests/GenerateSampleSpecificationTests.CheckCSharpClientsAsync_projectName=NSwag.Sample.NET70Minimal_targetFramework=net7.0_generatesCode=True.verified.txt b/src/NSwag.ConsoleCore.Tests/GenerateSampleSpecificationTests.CheckCSharpClientsAsync_projectName=NSwag.Sample.NET70Minimal_targetFramework=net7.0_generatesCode=True.verified.txt index 881d4e2b51..8e97fbdf8c 100644 --- a/src/NSwag.ConsoleCore.Tests/GenerateSampleSpecificationTests.CheckCSharpClientsAsync_projectName=NSwag.Sample.NET70Minimal_targetFramework=net7.0_generatesCode=True.verified.txt +++ b/src/NSwag.ConsoleCore.Tests/GenerateSampleSpecificationTests.CheckCSharpClientsAsync_projectName=NSwag.Sample.NET70Minimal_targetFramework=net7.0_generatesCode=True.verified.txt @@ -91,7 +91,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -174,7 +176,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -305,10 +309,19 @@ namespace MyNamespace { return System.Convert.ToBase64String((byte[]) value); } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } else if (value.GetType().IsArray) { - var array = System.Linq.Enumerable.OfType<object>((System.Array) value); - return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo)); + } + return string.Join(",", valueTextArray); } var result = System.Convert.ToString(value, cultureInfo); @@ -389,7 +402,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -518,10 +533,19 @@ namespace MyNamespace { return System.Convert.ToBase64String((byte[]) value); } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } else if (value.GetType().IsArray) { - var array = System.Linq.Enumerable.OfType<object>((System.Array) value); - return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo)); + } + return string.Join(",", valueTextArray); } var result = System.Convert.ToString(value, cultureInfo); diff --git a/src/NSwag.Sample.NET70Minimal/GeneratedClientsCs.gen b/src/NSwag.Sample.NET70Minimal/GeneratedClientsCs.gen index 3f53433a6a..b464f0ca78 100644 --- a/src/NSwag.Sample.NET70Minimal/GeneratedClientsCs.gen +++ b/src/NSwag.Sample.NET70Minimal/GeneratedClientsCs.gen @@ -91,7 +91,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -174,7 +176,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -305,10 +309,19 @@ namespace MyNamespace { return System.Convert.ToBase64String((byte[]) value); } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } else if (value.GetType().IsArray) { - var array = System.Linq.Enumerable.OfType<object>((System.Array) value); - return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo)); + } + return string.Join(",", valueTextArray); } var result = System.Convert.ToString(value, cultureInfo); @@ -389,7 +402,9 @@ namespace MyNamespace var disposeResponse_ = true; try { - var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; if (response_.Content != null && response_.Content.Headers != null) { foreach (var item_ in response_.Content.Headers) @@ -518,10 +533,19 @@ namespace MyNamespace { return System.Convert.ToBase64String((byte[]) value); } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } else if (value.GetType().IsArray) { - var array = System.Linq.Enumerable.OfType<object>((System.Array) value); - return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo))); + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo)); + } + return string.Join(",", valueTextArray); } var result = System.Convert.ToString(value, cultureInfo); diff --git a/src/NSwag.sln b/src/NSwag.sln index 5af5e15e45..78cc78694c 100644 --- a/src/NSwag.sln +++ b/src/NSwag.sln @@ -102,6 +102,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NSwag.ApiDescription.Client", "NSwag.ApiDescription.Client", "{E6E40935-0C79-480B-BF29-8C493AC7E518}" ProjectSection(SolutionItems) = preProject NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.nuspec = NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.nuspec + NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.props = NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.props NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.targets = NSwag.ApiDescription.Client\NSwag.ApiDescription.Client.targets EndProjectSection EndProject @@ -134,6 +135,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NSwag.Sample.NET80", "NSwag EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NSwag.Sample.NET80Minimal", "NSwag.Sample.NET80Minimal\NSwag.Sample.NET80Minimal.csproj", "{F0569608-BD55-4316-94F0-E85A14D7FE14}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FBF5AB11-68C3-41B8-9A08-5D25D6E814E4}" + ProjectSection(SolutionItems) = preProject + NuGet.Config = NuGet.Config + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/NuGet.Config b/src/NuGet.Config index 0c74ec458f..44dedea914 100644 --- a/src/NuGet.Config +++ b/src/NuGet.Config @@ -2,8 +2,8 @@ <configuration> <packageSources> <!--To inherit the global NuGet package sources remove the <clear/> line below --> - <clear /> + <!--<clear /> <add key="project" value="libs" /> - <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" /> + <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />--> </packageSources> </configuration>