Skip to content

[repo-assist] perf: string/int fast-paths in toParam; StringBuilder+String.Concat in buildXmlDoc#435

Merged
sergey-tihon merged 2 commits into
masterfrom
repo-assist/perf-toParam-fast-paths-20260514-dbabba98a21eb1a6
May 14, 2026
Merged

[repo-assist] perf: string/int fast-paths in toParam; StringBuilder+String.Concat in buildXmlDoc#435
sergey-tihon merged 2 commits into
masterfrom
repo-assist/perf-toParam-fast-paths-20260514-dbabba98a21eb1a6

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Two targeted performance improvements identified during routine codebase analysis.

1. RuntimeHelpers.toParam — fast-path arms for common scalar types

toParam is called for every query parameter, path parameter, and header value in every generated API client call. Previously, all types except DateTime and DateTimeOffset fell into the catch-all _ -> branch, which:

  1. Calls obj.GetType()
  2. Compares ty.FullName to dateOnlyTypeName
  3. Compares ty.FullName to timeOnlyTypeName
  4. Checks ty.IsGenericType
  5. Checks ty.IsEnum
  6. Finally calls obj.ToString()

For the most common OpenAPI scalar types — string, int32, int64, and bool — all five checks are wasted work.

Fix: add explicit match arms for these four types, short-circuiting directly to the result:

| :? string as s -> s
| :? int32 as i -> i.ToString()
| :? int64 as i -> i.ToString()
| :? bool as b -> b.ToString()

This avoids GetType() plus four branch evaluations per call for any parameter of these types.

2. Utils.buildXmlDoc — StringBuilder + String.Concat with 4 args

buildXmlDoc is called once per compiled operation at design time. Two minor allocations reduced:

  • paramParts: replaced [ for ... do yield ... ] |> String.concat "" (builds an F# cons-cell list then concatenates) with a StringBuilder loop — no intermediate list allocation.
  • Final join: replaced summaryPart + remarksPart + paramParts + returnsPart (two intermediate strings due to left-associative +) with String.Concat(summaryPart, remarksPart, paramParts, returnsPart) — single allocation.

Test Status

✅ All 417 unit tests pass
✅ Build succeeds (0 errors, warnings pre-existing)
✅ Fantomas format check passes

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@94ec5db57374c5b04a4b8eef8b4413f9af44d63f

…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>
@sergey-tihon sergey-tihon marked this pull request as ready for review May 14, 2026 22:21
Copilot AI review requested due to automatic review settings May 14, 2026 22:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Two micro-optimizations: a fast path in RuntimeHelpers.toParam for the most common scalar types (string/int32/int64/bool) to avoid reflection, and a StringBuilder/String.Concat rewrite of Utils.buildXmlDoc to reduce intermediate allocations.

Changes:

  • Add fast-path match arms for string, int32, int64, bool in toParam before the reflective fallback.
  • Replace list comprehension + String.concat "" with StringBuilder for assembling <param> parts in buildXmlDoc.
  • Replace chained + join of XML doc parts with String.Concat 4-arg overload.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/SwaggerProvider.Runtime/RuntimeHelpers.fs Adds scalar-type fast paths in toParam matching prior semantics (uses ToString() like previous fallback).
src/SwaggerProvider.DesignTime/Utils.fs Rewrites paramParts building with StringBuilder and joins final parts via String.Concat.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sergey-tihon sergey-tihon merged commit f06dc83 into master May 14, 2026
6 checks passed
@sergey-tihon sergey-tihon deleted the repo-assist/perf-toParam-fast-paths-20260514-dbabba98a21eb1a6 branch May 14, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants