From 1bdd3320b4df1334faab671d255c9a22573740ef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 17 May 2026 20:03:41 +0000 Subject: [PATCH 1/2] perf: replace formatObject Array.map+Join with StringBuilder Rewrite formatObject to stream directly into a StringBuilder instead of - allocating an intermediate string[] via Array.map - allocating per-property strings via 'p.Name + "=" + s' - allocating quoted-string via '"\"" + v.ToString() + "\""' - allocating array result via Array.ofSeq + '[' + Join + ']' - allocating outer wrapping via '{' + Join(strs) + '}' All 417 existing unit tests continue to pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/SwaggerProvider.Runtime/RuntimeHelpers.fs | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs index dbc2df3a..48b48c06 100644 --- a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs +++ b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs @@ -337,34 +337,44 @@ module RuntimeHelpers = /// Used by the emitted ToString() override to keep the generated method body O(1) in size. let formatObject(obj: obj) : string = let props = getProperties(obj.GetType()) + let sb = System.Text.StringBuilder() + sb.Append('{') |> ignore - let strs = - props - |> Array.map(fun p -> - let v = p.GetValue(obj) - - let s = - if isNull v then - "null" - else - let vTy = v.GetType() - - if vTy = typeof then - "\"" + v.ToString() + "\"" - elif vTy.IsArray then - let elements = - (v :?> Array) - |> Seq.cast - |> Seq.map(fun x -> if isNull x then "null" else x.ToString()) - |> Array.ofSeq - - "[" + String.Join("; ", elements) + "]" + for i in 0 .. props.Length - 1 do + if i > 0 then + sb.Append("; ") |> ignore + + let p = props[i] + sb.Append(p.Name).Append('=') |> ignore + let v = p.GetValue(obj) + + if isNull v then + sb.Append("null") |> ignore + else + let vTy = v.GetType() + + if vTy = typeof then + sb.Append('"').Append(v.ToString()).Append('"') |> ignore + elif vTy.IsArray then + sb.Append('[') |> ignore + let mutable firstEl = true + + for x in (v :?> Array) |> Seq.cast do + if not firstEl then + sb.Append("; ") |> ignore + + firstEl <- false + + if isNull x then + sb.Append("null") |> ignore else - v.ToString() + sb.Append(x.ToString()) |> ignore - p.Name + "=" + s) + sb.Append(']') |> ignore + else + sb.Append(v.ToString()) |> ignore - "{" + String.Join("; ", strs) + "}" + sb.Append('}').ToString() // Cached constructor for JsonPropertyNameAttribute to avoid repeated reflection lookups // when compiling large schemas with many properties. From 8a66384c51d8a8c5edab57c701ff74f492394025 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 May 2026 20:03:44 +0000 Subject: [PATCH 2/2] ci: trigger checks