dotnet / dotnet/efcore

Constant value handling in ExpressionEqualityComparer

Open
#29,006 0 comments 0 reactions 0 assignees View on GitHub
area-perf area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

#28581 was filed since array constants in query trees weren't compared correctly (hash code calculation, equality); this led to a cache miss for every query that contained an array literal, leading to continuous costly recompilation.

While #28720 fixed this specifically array literals (and tuples, or anything else that implements IStructuralEquatable), we still have this issue for constants of other types: lists, dictionaries, and possibly others (any type where Equals and GetHashCode aren't implemented for structural/value comparison). While constants of these are likely to be much rarer than array constants, we should consider fixing them as well.

On a related note, we may want to exclude constant values from the hash code calculation, and only include e.g. their CLR type. This would be an optimization as we no longer need to do potentially costly hash code calculations, and the expression tree shape and the constant type should provide enough hash code distribution. The theoretical downside is that all expressions which vary only by a constant value get the same hash code, and therefore would be stored under the same dictionary bucket. But that should only meaningfully occur when users erroneously build expression trees with constants instead of parameters ([this](https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-di%2Cwith-constant#dynamically-constructed-queries)).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.