Skip to content

Unpickling: share one EntityRef per non-local reference row - #20364

Merged
T-Gro merged 1 commit into
dotnet:mainfrom
auduchinok:pickle-shareTypeRefWrappers-main
Aug 27, 2026
Merged

Unpickling: share one EntityRef per non-local reference row#20364
T-Gro merged 1 commit into
dotnet:mainfrom
auduchinok:pickle-shareTypeRefWrappers-main

Conversation

@auduchinok

Copy link
Copy Markdown
Member

u_tcref wrapped a fresh EntityRef around the shared NonLocalEntityRef on every mention. Reading a
489-reference project that is 88642 wrappers around 1919 rows — 46 per row.

They are all equal. An EntityRef is the row plus a binding field that caches the resolution, and the
resolution is a function of the row, so sharing one wrapper per row also resolves once instead of once per
mention. The cache is an array beside the inlerefs table, keyed by the row index that is already being
read, so there is no lookup and no hashing.

project base change delta
FSharp.Common 141.2 138.5 −2.68 (−1.9%)
Fantomas.Core.Tests 75.7 73.9 −1.77 (−2.3%)
Fantomas.Benchmarks 52.4 50.7 −1.73 (−3.3%)
Fantomas.Core 57.1 55.7 −1.37 (−2.4%)
FSharp.Compiler.Service 359.4 358.4 −1.03 (−0.3%)
Oxpecker 50.4 49.9 −0.54 (−1.1%)
consoleapp 28.3 27.9 −0.42 (−1.5%)
IcedTasks 26.3 25.9 −0.38 (−1.4%)
FsToolkit.ErrorHandling 31.6 31.2 −0.38 (−1.2%)
Prime 39.9 39.6 −0.31 (−0.8%)
solution base change delta
FSharp.Compiler.Service repo 731.7 724.8 −6.86 (−0.9%)
Fantomas 291.3 287.2 −4.10 (−1.4%)
ReSharper.FSharp 293.0 290.4 −2.59 (−0.9%)
IcedTasks 90.1 88.3 −1.83 (−2.0%)
Prime 99.2 98.0 −1.23 (−1.2%)
Oxpecker 110.0 109.1 −0.95 (−0.9%)
FsToolkit.ErrorHandling 66.8 66.1 −0.66 (−1.0%)
consoleapp 28.3 28.0 −0.33 (−1.2%)

Correctness

  • Diagnostic counts identical in every cell of both sweeps (ReSharper.FSharp 1, this repo 413, Fantomas 20,
    the rest 0).
  • Sharing the wrapper shares the binding cache. That is sound because the binding is derived from the
    row and nothing else: two mentions of the same row must resolve to the same entity or the existing
    per-mention resolution would already be inconsistent.
  • The cache is per ReaderState, so it never spans two pickled blobs.
  • Time: neutral. Measured 2026-08-23 as one rung of a 4-rung cumulative ladder, 5 rounds, 30 samples per
    cell: +0.2% on ReSharper.FSharp and +0.4% on Oxpecker against a +0.6% A/A control.
  • Not run: the test suite.

`u_tcref` wrapped a fresh `EntityRef` around the shared `NonLocalEntityRef` on every mention. Reading a
489-reference project that is 88642 wrappers around 1919 rows - 46 per row - and they are all equal:
an `EntityRef` is the row plus a `binding` cache that resolves deterministically from it, so sharing one
per row also means resolving once instead of once per mention.

Cached in an array beside the `inlerefs` table, so the key is the row index that is already being read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SSWUAYfpj82BHvzpkUCy8Z
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

⚠️ Release notes required, but author opted out

Warning

Author opted out of release notes, check is disabled for this pull request.
cc @dotnet/fsharp-team-msft

@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Aug 26, 2026
@T-Gro T-Gro added the NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes label Aug 27, 2026
@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Aug 27, 2026
@T-Gro
T-Gro merged commit ef4f617 into dotnet:main Aug 27, 2026
59 of 60 checks passed
@auduchinok
auduchinok deleted the pickle-shareTypeRefWrappers-main branch August 27, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants