Reduce allocations in Md5Hasher and fix broken ThreadLocal<MD5> reuse - #20275
Open
xperiandri wants to merge 1 commit into
Open
Reduce allocations in Md5Hasher and fix broken ThreadLocal<MD5> reuse#20275xperiandri wants to merge 1 commit into
ThreadLocal<MD5> reuse#20275xperiandri wants to merge 1 commit into
Conversation
Contributor
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
|
ThreadLocal<MD5> reuse
xperiandri
force-pushed
the
hashing-improvements
branch
from
August 17, 2026 01:26
d3f950c to
2219dc8
Compare
T-Gro
approved these changes
Aug 17, 2026
T-Gro
left a comment
Member
There was a problem hiding this comment.
Nice cleanup — the ThreadLocal<MD5> is finally doing its job, and the pooled encode buffer plus the no-copy AsImmutableArray wrap remove real per-checksum allocations on a hot path.
Verified the parts that could have bitten:
hashStringToStringkeepsBitConverter.ToString's dashed format, soFSharpProjectSnapshotversion strings are unchanged.- The
AsImmutableArraywrap is safe here: bothGetChecksumsites hand it a freshly-allocated 16-byte local that's never aliased afterwards. ImmutableCollectionsMarshal.AsImmutableArrayis unguarded but ships in thenetstandard2.0target of System.Collections.Immutable since 8.0.0, and the repo floor is 10.0.9, so both TFMs compile.Md5Hasher.hashStringis fully removed with no remaining callers, andMd5Hasheris internal, so no surface-area impact.
Two optional nits, neither blocking:
- The
#elsepath ignoresMD5.TryHashData's bool result. It can't fail with an exact 16-byte destination, but anassert/invalidOponfalsewould document that invariant. - The XML-doc blocks are a touch long for a facilities helper; a one-liner each would read fine.
T-Gro
self-requested a review
August 17, 2026 08:34
xperiandri
force-pushed
the
hashing-improvements
branch
2 times, most recently
from
August 17, 2026 11:45
b7c5260 to
4447fb4
Compare
xperiandri
force-pushed
the
hashing-improvements
branch
from
August 17, 2026 12:14
4447fb4 to
8d9043c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #20204
Changes
Md5Hasher.computeHashnow actually reuses the thread-localMD5instance underNETSTANDARD2_0(previously a newMD5instance was created on every call, with aTODOcomment noting theThreadLocal"wasn't working"), and usesMD5.HashDataon modern TFMs.Md5Hasher.hashStringInto, which hashes a string directly into a caller-supplied 16-byteSpan<byte>, renting the UTF8 encoding buffer fromArrayPool<byte>.Sharedinstead of allocating a new byte array per call.Md5Hasher.hashStringToString, producing the hex-string hash of a string without a separatehashString |> toStringallocation.hashStringis now implemented in terms ofhashStringInto.prim-lexing.fs,FSharpProjectSnapshot.fs) to use the new allocation-reduced helpers.