Skip to content

refactor: Optimize MobileBy FindElements to reduce list allocations - #1103

Merged
Dor-bl merged 2 commits into
appium:mainfrom
Dor-bl:perf/mobileby-read-only-collection-allocation-6392073121482763632
Aug 21, 2026
Merged

refactor: Optimize MobileBy FindElements to reduce list allocations#1103
Dor-bl merged 2 commits into
appium:mainfrom
Dor-bl:perf/mobileby-read-only-collection-allocation-6392073121482763632

Conversation

@Dor-bl

@Dor-bl Dor-bl commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

List of changes

This pull request refactors how ReadOnlyCollection<IWebElement> is created in the MobileBy class, improving code efficiency and consistency. The main change is the removal of unnecessary .ToList() calls before converting collections to read-only, and the introduction of a new extension method to handle this conversion more robustly.

Refactoring and Code Simplification

  • Replaced all usages of .ToList().AsReadOnly() with a new AsReadOnly() extension method, which ensures that collections are converted to ReadOnlyCollection<T> efficiently and safely. (src/Appium.Net/Appium/MobileBy.cs, src/Appium.Net/Appium/ReadOnlyCollectionExtensions.cs) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

Code Organization

  • Added a new file, ReadOnlyCollectionExtensions.cs, containing the AsReadOnly extension method for IReadOnlyCollection<T>, centralizing the logic for converting collections.

Minor Cleanup

  • Removed an unnecessary using System.Linq; directive from MobileBy.cs since it is no longer needed after the refactor.

These changes make the codebase cleaner, reduce unnecessary list allocations, and improve maintainability.

Types of changes

What types of changes are you proposing/introducing to the .NET client?
Put an x in the boxes that apply

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change that adds functionality or value)
  • Breaking change (fix or feature that would cause existing functionality not to work as expected)
  • Test fix (non-breaking change that improves test stability or correctness)
  • Chore/Maintenance (updates to build scripts, dependencies, or GitHub Actions)

Documentation

  • Have you proposed a file change/ PR with Appium to update documentation?

This can be done by navigating to the documentation section on http://appium.io selecting the appropriate command/endpoint and clicking the 'Edit this doc' link to update the C# example

Integration tests

  • Have you provided integration tests for your changes? (required for Bugfix, New feature, or Test fix)

Details

Please provide more details about changes if necessary. You can provide code samples showing how they work and possible use cases if there are new features. Also, you can create gists with pasted C# code samples or put them here using markdown.
About markdown please read Mastering markdown and Writing on GitHub

Dor-bl and others added 2 commits March 22, 2026 21:34
Replaced unnecessary `ToList().AsReadOnly()` calls with a smart `AsReadOnly()` extension method that uses the underlying `IList` if available. This avoids redundant O(N) memory allocations and array copies when wrapping the results of `FindElements`.
Copilot AI lite review requested due to automatic review settings August 19, 2026 20:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 refactors how MobileBy converts IReadOnlyCollection<IWebElement> results into ReadOnlyCollection<IWebElement>, aiming to reduce unnecessary allocations by avoiding eager .ToList().AsReadOnly() conversions and centralizing the conversion logic in a shared helper.

Changes:

  • Replaced multiple .ToList().AsReadOnly() usages in MobileBy.FindElements(...) overrides with a new AsReadOnly() extension method.
  • Added ReadOnlyCollectionExtensions.AsReadOnly<T>(this IReadOnlyCollection<T>) to standardize conversion to ReadOnlyCollection<T>.
  • Removed using System.Linq; from MobileBy.cs since it’s no longer directly needed there.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Appium.Net/Appium/MobileBy.cs Switches element-collection conversion to the new AsReadOnly() helper to reduce per-call allocations.
src/Appium.Net/Appium/ReadOnlyCollectionExtensions.cs Introduces a shared conversion helper for IReadOnlyCollection<T>ReadOnlyCollection<T>.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1 to +18
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace OpenQA.Selenium.Appium
{
internal static class ReadOnlyCollectionExtensions
{
internal static ReadOnlyCollection<T> AsReadOnly<T>(this IReadOnlyCollection<T> collection)
{
if (collection is ReadOnlyCollection<T> readOnlyCollection)
{
return readOnlyCollection;
}
return new ReadOnlyCollection<T>(collection as IList<T> ?? collection.ToList());
}
}
}
@Dor-bl
Dor-bl merged commit 44c4222 into appium:main Aug 21, 2026
7 checks passed
{
return readOnlyCollection;
}
return new ReadOnlyCollection<T>(collection as IList<T> ?? collection.ToList());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

potential NRE at collection.ToList()

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.

4 participants