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