-
Notifications
You must be signed in to change notification settings - Fork 255
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
While working on our benchmarks, I faced a peculiar issue. Some of the unreachable code in our validators and evaluators is allocating memory. It seems an enumerator is created even though we never reach that section. Here is an example.
public bool IsValid<T>(T entity, ISpecification<T> specification)
{
if (specification is Specification<T> spec)
{
if (spec.OneOrManySearchExpressions.IsEmpty) return true;
if (spec.OneOrManySearchExpressions.SingleOrDefault is { } searchExpression)
{
return searchExpression.SelectorFunc(entity)?.Like(searchExpression.SearchTerm) ?? false;
}
// The search expressions are already sorted by SearchGroup.
return IsValid(entity, spec.OneOrManySearchExpressions.List);
}
// We'll never reach this point for our specifications.
// This is just to cover the case where users have custom ISpecification<T> implementation but use our validator.
// We'll fall back to LINQ for this case.
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))
{
if (!searchGroup.Any(c => c.SelectorFunc(entity)?.Like(c.SearchTerm) ?? false))
return false;
}
return true;
}
If we move the fallback code to a local function, allocations go away. So, I assume some compiler (or even runtime) optimizations mess up our assumptions. We should apply this fix wherever applicable.
PS. We'll categorize this as a bug. It's not a bug per se, the behavior remains correct, there are just unnecessary allocations.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working