Skip to content
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

Fix quadratic performance issue in AsyncQueue<Serial> #1840

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Nov 22, 2024

Adding an item to AsyncQueue was linear in the number of pending queue items, thus adding n items to an AsyncQueue before any can execute is in O(n^2). This decision was made intentionally because the primary use case for AsyncQueue was to track pending LSP requests, of which we don’t expect to have too many pending requests at any given time.

While we can't fix the quadratic performance issue in general, we can resolve the quadratic issue of AsyncQueue<Serial> by making a new task only depend on the last item in the queue, which then transitively depends on all the previous items. AsyncQueue<Serial> are the queues that are most likely to contain many items.

Fixes #1725
rdar://137886469

Adding an item to `AsyncQueue` was linear in the number of pending queue items, thus adding n items to an `AsyncQueue` before any can execute is in O(n^2). This decision was made intentionally because the primary use case for `AsyncQueue` was to track pending LSP requests, of which we don’t expect to have too many pending requests at any given time.

While we can't fix the quadratic performance issue in general, we can resolve the quadratic issue of `AsyncQueue<Serial>` by making a new task only depend on the last item in the queue, which then transitively depends on all the previous items. `AsyncQueue<Serial>` are the queues that are most likely to contain many items.

Fixes swiftlang#1725
rdar://137886469
@ahoppen
Copy link
Member Author

ahoppen commented Nov 22, 2024

@swift-ci Please test

Comment on lines -31 to -33
/// Whether the task described by `self` needs to finish executing before
/// `other` can start executing.
func isDependency(of other: Self) -> Bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Could keep both requirements and add a default implementation of dependencies(in:) that does the filtering. Don't really mind though

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it’s good to make adopters a little more aware of the potentially quadratic issue.

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.

Quadratic performance issue in AsyncQueue
2 participants