[Repo Assist] perf: avoid FSharpValue.GetUnionFields in toParam via cached tag reader#399
Conversation
Replace the FSharpValue.GetUnionFields call in toParam (used when unwrapping F# option values for query/form parameters) with a precomputed union-tag reader. GetUnionFields allocates a UnionCaseInfo object and an obj[] on every call. The new approach: - Caches FSharpValue.PreComputeUnionTagReader per option type (O(1) tag check with no allocation after first call) - Caches the Value PropertyInfo per option type (shared with unwrapFSharpOption) - Removes the now-redundant private optionValuePropCache, consolidating both caches in one place This matters for APIs that send many optional query/form parameters; the improvement is visible when profiling clients that call high- frequency endpoints with optional fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR optimizes runtime parameter serialization by reducing allocations when unwrapping F# option<'T> values in RuntimeHelpers.toParam, replacing FSharpValue.GetUnionFields with a cached, precomputed union tag reader.
Changes:
- Added a cached
PreComputeUnionTagReaderper concreteoption<'T>type to avoidGetUnionFieldsallocations on repeated calls. - Consolidated/cached reflection for the
Valueproperty into a sharedoptionValueCacheused by bothtoParamandunwrapFSharpOption.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/aa9c5b07-4c10-4389-b812-170f423a4acc Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🤖 This PR was created by Repo Assist, an automated AI assistant.
Summary
Replaces the
FSharpValue.GetUnionFieldscall inRuntimeHelpers.toParamwith a precomputed, cached union tag reader.Problem
When serializing optional query/form parameters,
toParamunwrapped F#option<T>values usingFSharpValue.GetUnionFields. On every call this allocates:UnionCaseInfoobjectobj[]of field valuesThis overhead accumulates for APIs that send many optional parameters, especially in tight loops or high-frequency endpoints.
Fix
optionTagReaderCache: maps eachoption<T>type to a precomputedFSharpValue.PreComputeUnionTagReaderresult. After the first call per type, tag reading is allocation-free.optionValueCache: maps eachoption<T>to its cachedValuePropertyInfo. Shared withunwrapFSharpOption, eliminating the now-redundantoptionValuePropCache.tag = 1(Some) then access.Valuevia the cached property.Before / After
GetUnionFields→ allocatesUnionCaseInfo+obj[]values.[0]from theobj[]PropertyInfo.GetValueTest Status
✅ All 327 unit tests pass (
dotnet tests/SwaggerProvider.Tests/bin/Release/net10.0/SwaggerProvider.Tests.dll)✅ Fantomas format check passes