From 1671a30cb6b70110bd9f55c547d140e76dca313a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 20:09:41 +0000 Subject: [PATCH 1/2] perf: add string/int fast-paths in toParam; use StringBuilder+String.Concat in buildXmlDoc - toParam: add explicit match arms for string, int32, int64, bool to skip GetType() + four type checks (two FullName comparisons, IsGenericType, IsEnum) for the most common OpenAPI scalar parameter types. - buildXmlDoc (Utils.fs): replace list-comprehension + String.concat for paramParts with a StringBuilder loop to avoid F# list cons-cell allocation; replace the final four-way string concatenation with String.Concat(a,b,c,d) to avoid two intermediate string allocations per compiled operation. All 417 unit tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/SwaggerProvider.DesignTime/Utils.fs | 16 +++++++++++----- src/SwaggerProvider.Runtime/RuntimeHelpers.fs | 7 +++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/SwaggerProvider.DesignTime/Utils.fs b/src/SwaggerProvider.DesignTime/Utils.fs index ac5f7d6b..49d9ad64 100644 --- a/src/SwaggerProvider.DesignTime/Utils.fs +++ b/src/SwaggerProvider.DesignTime/Utils.fs @@ -372,17 +372,23 @@ module XmlDoc = $"{escapeXml description}" let paramParts = - [ for name, desc in paramDescriptions do - if not(String.IsNullOrWhiteSpace desc) then - yield $"{escapeXml desc}" ] - |> String.concat "" + let sb = System.Text.StringBuilder() + + for name, desc in paramDescriptions do + if not(String.IsNullOrWhiteSpace desc) then + sb.Append("").Append(escapeXml desc).Append("") + |> ignore + + sb.ToString() let returnsPart = match returnDoc with | Some rd when not(String.IsNullOrWhiteSpace rd) -> $"{escapeXml rd}" | _ -> "" - summaryPart + remarksPart + paramParts + returnsPart + // Use String.Concat with 4 arguments instead of chained + operators to avoid + // two intermediate string allocations (one per + in `a + b + c + d`). + String.Concat(summaryPart, remarksPart, paramParts, returnsPart) type UniqueNameGenerator(?occupiedNames: string seq) = let hash = System.Collections.Generic.HashSet<_>() diff --git a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs index 504c38f3..dbc2df3a 100644 --- a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs +++ b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs @@ -211,6 +211,13 @@ module RuntimeHelpers = | :? DateTime as dt -> dt.ToString("O") | :? DateTimeOffset as dto -> dto.ToString("O") | null -> null + // Fast paths for the most common scalar param types: + // these avoid calling GetType() and the four subsequent type checks + // (FullName twice, IsGenericType, IsEnum) that follow in the generic branch. + | :? string as s -> s + | :? int32 as i -> i.ToString() + | :? int64 as i -> i.ToString() + | :? bool as b -> b.ToString() | _ -> // Hoist GetType() once; previously tryFormatDateOnly and tryFormatTimeOnly // each called GetType() internally, resulting in up to 3 GetType() calls for From 9a4e5a6d1ba68e262b720b5bdb9a56ad275b9932 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 May 2026 20:09:44 +0000 Subject: [PATCH 2/2] ci: trigger checks