Skip to content

Conversation

@cincuranet
Copy link
Contributor

@cincuranet cincuranet commented Dec 7, 2025

Fixes #37152.

🔢

Method Job Arguments Count Mean Error StdDev Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
Manual 10.0.0 /p:EFVersion=10.0.0 1000 17,873.4 us 135.77 us 127.00 us 11.21 0.25 3500.0000 187.5000 31.2500 28701.33 KB 18.00
Manual 9.0.11 /p:EFVersion=9.0.11 1000 1,595.5 us 31.07 us 33.24 us 1.00 0.03 187.5000 109.3750 31.2500 1594.15 KB 1.00
Manual current Default 1000 1,620.6 us 28.11 us 32.37 us 1.02 0.03 218.7500 125.0000 31.2500 1893.34 KB 1.19
Contains 10.0.0 /p:EFVersion=10.0.0 1000 21,901.9 us 263.62 us 246.59 us 202.41 4.23 8781.2500 31.2500 - 71871.2 KB 448.59
Contains 9.0.11 /p:EFVersion=9.0.11 1000 108.2 us 2.16 us 2.02 us 1.00 0.03 19.5313 2.4414 - 160.22 KB 1.00
Contains current Default 1000 563.7 us 10.96 us 18.00 us 5.21 0.19 195.3125 - - 1635.02 KB 10.21

💭

The Manual benchmark is now very close to what it used to be in 9. The 2% difference in speed (some runs showed 5%, the Error/StdDev here is pretty high) is the "price" for now much more nicer parameter names.

The Contains benchmark is not comparing 🍎 and 🍎. In 9, the query was translated to OPENJSON, while in 10 this is translated to multiple parameters. Before the fix the translation was very slow (~188x) and created a lot of allocations (~448x). Now the numbers are ~5x and ~10x. Again, this is comparing 1 parameter vs 1000 parameters - 🍎 vs 🍊.

Fair to say, I know about a decent room for improvement in allocations (hence theoretically in speed as well, at least in benchmarks). But it is too risky for servicing. I might do it for 11.

It is also important to know that this benchmark measures only the translation. Once the query hits the database, the translation to multiple parameters should show its real benefits.

Description

EF 10 changed the default translation for parameterized collections from single parameter and JSON function to multiple parameters. We missed O(n^2) performance degradation in code path where we generate unique parameter names resulting in subpar performance.

Customer impact

Query translation takes significant time compared to other types of translation. Excessive allocations.

How found

Customer reported on 10.0.

Regression

Yes.

Testing

The change in the PR is covered by existing tests. We don't have specific benchmarks for translations.

Risk

Low. Added fast path optimization. Quirk added.

@cincuranet cincuranet added this to the 10.0.2 milestone Dec 7, 2025
* Reduce allocations.
* Allow for less looping when `uniquifier` is provided.
* This partially reverts back to previous behavior of having a running count.
* But still uses the new naming.
@cincuranet cincuranet force-pushed the perf branch 2 times, most recently from b910fcf to 9c94053 Compare December 8, 2025 07:41
@cincuranet cincuranet marked this pull request as ready for review December 8, 2025 08:21
@cincuranet cincuranet requested a review from a team as a code owner December 8, 2025 08:21
Copy link
Member

@roji roji left a comment

Choose a reason for hiding this comment

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

LGTM, thanks.

@cincuranet cincuranet force-pushed the perf branch 2 times, most recently from 3fafe58 to 4a261b0 Compare December 8, 2025 12:27
@cincuranet cincuranet requested a review from artl93 December 8, 2025 13:23
@cincuranet
Copy link
Contributor Author

cincuranet commented Dec 8, 2025

cc @artl93
56 files looks big, but the changes are mostly test in files. The actual code is small.
For 11.0 there's more performance available and I'll do it. But for servicing we kept it small.

Copy link
Member

@artl93 artl93 left a comment

Choose a reason for hiding this comment

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

Customer reported, performance, regression. Approved.

@cincuranet
Copy link
Contributor Author

Approved via email.

@cincuranet cincuranet merged commit df9c217 into dotnet:release/10.0 Dec 9, 2025
7 checks passed
@cincuranet cincuranet deleted the perf branch December 9, 2025 10:08
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.

EF Core 10 queries much slower than EF Core 9 with a larger number of parameters

4 participants