Skip to content

Commit 3604382

Browse files
feat: Remove default collection initialization for perf reasons (#2284)
* feat: use lazy get for collection initialization to reduce resource allocation * chore: use Lazy<T> pattern; preserve null values * chore: replicate for collections in other components * chore: remove unnecessary usings * fix: revert lazy initialization; remove collection initialization * chore: initialize collections to prevent NREs * chore: fix failing tests * chore: revert changes * chore: remove default collection initialization across all models; clean up and fix tests * chore: clean up code; initialize collections where applicable * chore: more cleanup * chore: move assignment within the condition * chore: replace interface with concrete type * chore: simplify collection initialization * Update src/Microsoft.OpenApi/Models/OpenApiPathItem.cs Co-authored-by: Vincent Biret <vibiret@microsoft.com> * chore: implement PR feedback * chore: reverts casing change --------- Co-authored-by: Vincent Biret <vibiret@microsoft.com>
1 parent 136a724 commit 3604382

File tree

142 files changed

+1357
-1318
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+1357
-1318
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ var document = new OpenApiDocument
5555
{
5656
["/pets"] = new OpenApiPathItem
5757
{
58-
Operations = new Dictionary<HttpMethod, OpenApiOperation>
58+
Operations = new()
5959
{
6060
[HttpMethod.Get] = new OpenApiOperation
6161
{

src/Microsoft.OpenApi.Hidi/Extensions/OpenApiExtensibleExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ internal static class OpenApiExtensibleExtensions
1313
/// <param name="extensions">A dictionary of <see cref="IOpenApiExtension"/>.</param>
1414
/// <param name="extensionKey">The key corresponding to the <see cref="IOpenApiExtension"/>.</param>
1515
/// <returns>A <see cref="string"/> value matching the provided extensionKey. Return null when extensionKey is not found. </returns>
16-
internal static string GetExtension(this IDictionary<string, IOpenApiExtension> extensions, string extensionKey)
16+
internal static string GetExtension(this Dictionary<string, IOpenApiExtension> extensions, string extensionKey)
1717
{
1818
if (extensions.TryGetValue(extensionKey, out var value) && value is OpenApiAny { Node: JsonValue castValue } && castValue.TryGetValue<string>(out var stringValue))
1919
{

src/Microsoft.OpenApi.Hidi/Extensions/StringExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static bool IsEquals(this string? target, string? searchValue, StringComp
3434
/// <param name="target">The target string to split by char. </param>
3535
/// <param name="separator">The char separator.</param>
3636
/// <returns>An <see cref="IList{String}"/> containing substrings.</returns>
37-
public static IList<string> SplitByChar(this string target, char separator)
37+
public static List<string> SplitByChar(this string target, char separator)
3838
{
3939
if (string.IsNullOrWhiteSpace(target))
4040
{

src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public override void Visit(OpenApiOperation operation)
7777
// Order matters. Resolve operationId.
7878
operationId = RemoveHashSuffix(operationId);
7979
if (operationTypeExtension.IsEquals("action") || operationTypeExtension.IsEquals("function"))
80-
operationId = RemoveKeyTypeSegment(operationId, operation.Parameters ?? new List<IOpenApiParameter>());
80+
operationId = RemoveKeyTypeSegment(operationId, operation.Parameters ?? []);
8181
operationId = SingularizeAndDeduplicateOperationId(operationId.SplitByChar('.'));
8282
operationId = ResolveODataCastOperationId(operationId);
8383
operationId = ResolveByRefOperationId(operationId);
@@ -119,7 +119,7 @@ private static string ResolveODataCastOperationId(string operationId)
119119
return match.Success ? $"{match.Groups[1]}{match.Groups[2]}" : operationId;
120120
}
121121

122-
private static string SingularizeAndDeduplicateOperationId(IList<string> operationIdSegments)
122+
private static string SingularizeAndDeduplicateOperationId(List<string> operationIdSegments)
123123
{
124124
var segmentsCount = operationIdSegments.Count;
125125
var lastSegmentIndex = segmentsCount - 1;
@@ -145,7 +145,7 @@ private static string RemoveHashSuffix(string operationId)
145145
return s_hashSuffixRegex.Match(operationId).Value;
146146
}
147147

148-
private static string RemoveKeyTypeSegment(string operationId, IList<IOpenApiParameter> parameters)
148+
private static string RemoveKeyTypeSegment(string operationId, List<IOpenApiParameter> parameters)
149149
{
150150
var segments = operationId.SplitByChar('.');
151151
foreach (var parameter in parameters)
@@ -159,9 +159,9 @@ private static string RemoveKeyTypeSegment(string operationId, IList<IOpenApiPar
159159
return string.Join('.', segments);
160160
}
161161

162-
private static void ResolveFunctionParameters(IList<IOpenApiParameter> parameters)
162+
private static void ResolveFunctionParameters(List<IOpenApiParameter> parameters)
163163
{
164-
foreach (var parameter in parameters.OfType<OpenApiParameter>().Where(static p => p.Content?.Any() ?? false))
164+
foreach (var parameter in parameters.OfType<OpenApiParameter>().Where(static p => p.Content?.Count > 0))
165165
{
166166
// Replace content with a schema object of type array
167167
// for structured or collection-valued function parameters

src/Microsoft.OpenApi.Hidi/StatsVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public override void Visit(IOpenApiSchema schema)
2727

2828
public int HeaderCount { get; set; }
2929

30-
public override void Visit(IDictionary<string, IOpenApiHeader> headers)
30+
public override void Visit(Dictionary<string, IOpenApiHeader> headers)
3131
{
3232
HeaderCount++;
3333
}

src/Microsoft.OpenApi.Workbench/StatsVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public override void Visit(IOpenApiSchema schema)
2727

2828
public int HeaderCount { get; set; }
2929

30-
public override void Visit(IDictionary<string, IOpenApiHeader> headers)
30+
public override void Visit(Dictionary<string, IOpenApiHeader> headers)
3131
{
3232
HeaderCount++;
3333
}

src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
56
using Microsoft.OpenApi.Exceptions;
67
using Microsoft.OpenApi.Interfaces;
78
using Microsoft.OpenApi.Models;
@@ -32,10 +33,8 @@ public static void AddExtension<T>(this T element, string name, IOpenApiExtensio
3233
throw new OpenApiException(string.Format(SRResource.ExtensionFieldNameMustBeginWithXDash, name));
3334
}
3435

35-
if (element.Extensions is not null)
36-
{
37-
element.Extensions[name] = Utils.CheckArgumentNull(any);
38-
}
36+
element.Extensions ??= [];
37+
element.Extensions[name] = Utils.CheckArgumentNull(any);
3938
}
4039
}
4140
}

src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public static class OpenApiServerExtensions
2121
/// 1. A substitution has no valid value in both the supplied dictionary and the default
2222
/// 2. A substitution's value is not available in the enum provided
2323
/// </exception>
24-
public static string? ReplaceServerUrlVariables(this OpenApiServer server, IDictionary<string, string>? values = null)
24+
public static string? ReplaceServerUrlVariables(this OpenApiServer server, Dictionary<string, string>? values = null)
2525
{
2626
var parsedUrl = server.Url;
2727
if (server.Variables is not null && parsedUrl is not null)

src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ public interface IMetadataContainer
1414
/// <summary>
1515
/// A collection of properties associated with the current OpenAPI element.
1616
/// </summary>
17-
IDictionary<string, object>? Metadata { get; set; }
17+
Dictionary<string, object>? Metadata { get; set; }
1818
}
1919
}

src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public interface IOpenApiExtensible : IOpenApiElement
1313
/// <summary>
1414
/// Specification extensions.
1515
/// </summary>
16-
IDictionary<string, IOpenApiExtension>? Extensions { get; set; }
16+
Dictionary<string, IOpenApiExtension>? Extensions { get; set; }
1717
}
1818
}

0 commit comments

Comments
 (0)