Skip to content

Optimize VisitList<>() #372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2025
Merged

Optimize VisitList<>() #372

merged 1 commit into from
Apr 17, 2025

Conversation

SergeiPavlov
Copy link
Collaborator

@SergeiPavlov SergeiPavlov commented Apr 16, 2025

Most usage case don't require IReadOnlyList<>.

IEnumerable<> is enough. This allows to avoid allocating intermediate arrays when unnecessary

@snaumenko-st snaumenko-st requested a review from Copilot April 17, 2025 12:56
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR optimizes the transformation of element lists in expression visitors to avoid unnecessary intermediate allocations. Key changes include converting Visit*List methods to yield IEnumerable, refactoring VisitList to return the original collection when possible, and adding a ToReadOnlyList extension to support compatibility with APIs expecting IReadOnlyList.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
Orm/Xtensive.Orm/Orm/Linq/Expressions/Visitors/OwnerRemover.cs Applies ToReadOnlyList conversion to adapt to changes in VisitList return type.
Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs Changes Visit*List methods' return types from IReadOnlyList to IEnumerable and refactors VisitList.
Orm/Xtensive.Orm/Core/Extensions/EnumerableExtensions.cs Introduces ToReadOnlyList extension to convert IEnumerable sequences to IReadOnlyList.
Comments suppressed due to low confidence (2)

Orm/Xtensive.Orm/Orm/Linq/Expressions/Visitors/OwnerRemover.cs:70

  • Verify that converting newConstructorArguments to a read-only list at this point is necessary, as it might introduce an extra allocation if newConstructorArguments is already an IReadOnlyList. Consider ensuring that the conversion is applied consistently with the intended performance benefits.
return new ConstructorExpression(expression.Type, bindings, nativeBingings, expression.Constructor, newConstructorArguments.ToReadOnlyList());

Orm/Xtensive.Orm/Linq/ExpressionVisitor.cs:246

  • [nitpick] The refactored VisitList now defers transformation via lazy evaluation which may result in multiple invocations of func for the later elements. Ensure that func is side-effect free and has acceptable performance characteristics, or consider materializing the results immediately if multiple enumerations are expected.
if (func(originalValue) is var p && !ReferenceEquals(p, originalValue)) {

@SergeiPavlov SergeiPavlov merged commit f7688d5 into master-servicetitan Apr 17, 2025
5 checks passed
@SergeiPavlov SergeiPavlov deleted the VisitList branch April 17, 2025 16:54

internal static IReadOnlyList<T> ToReadOnlyList<T>(this IEnumerable<T> seq) =>
seq switch {
IReadOnlyList<T> roList => roList,
Copy link

Choose a reason for hiding this comment

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

            IList<T> list => list.Count is var count && count == 0
                ? []
                : ReferenceArraySegment<T>.TryCreate(list, count) ?? new ReadOnlyCollection<T>(list),

in mono we have optimization for empty List

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants