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

avm1: Replace recursion with iterative qsort #18626

Merged
merged 2 commits into from
Dec 4, 2024

Conversation

123jjck
Copy link
Contributor

@123jjck 123jjck commented Nov 17, 2024

Fixes #18109

Speeds up sorting

var arr = [];
var i = 0;
while(i < 3000)
{
   arr.push({key:i});
   i++;
}

flash.external.ExternalInterface.call("console.log",arr[0]);

var startDate = new Date();
flash.external.ExternalInterface.call("console.log","Sorting started at: " + startDate);

arr.sortOn("key",Array.DESCENDING | Array.NUMERIC);

var endDate = new Date();
flash.external.ExternalInterface.call("console.log","Sorting ended at: " + endDate);

flash.external.ExternalInterface.call("console.log",arr[0]);

var duration = endDate.getTime() - startDate.getTime();
flash.external.ExternalInterface.call("console.log","Sorting duration (ms): " + duration);

In this example:
Recursion qsort duration: 347ms
Iterative qsort duration: 271ms

@kjarosh kjarosh added A-avm1 Area: AVM1 (ActionScript 1 & 2) T-perf Type: Performance Improvements labels Nov 17, 2024
Copy link
Collaborator

@adrian17 adrian17 left a comment

Choose a reason for hiding this comment

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

Thank you! Sorry for a delay, I added some review comments. I think this looks fine, though I'm kinda surprised at the 20% speedup.

core/src/avm1/globals/array.rs Outdated Show resolved Hide resolved
stack.push((0, elements.len() - 1));

while let Some((low, high)) = stack.pop() {
if low >= high {
Copy link
Collaborator

Choose a reason for hiding this comment

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

> isn't normally possible, right? Can we assert that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

> isn't normally possible, right?

Yes, you're right! Should I use assert! or debug_assert! for this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

assert does sound nice, unless it kills the performance back.

Copy link
Contributor Author

@123jjck 123jjck Dec 3, 2024

Choose a reason for hiding this comment

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

I think we can't replace the if condition with assert because low >= high can occur when the pivot partition results in a subarray with no elements. (e.g., [5, 5, 5, 5, 5])

Copy link
Collaborator

Choose a reason for hiding this comment

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

I know low == high can occur, but I meant that specifically low > high shouldn't ever occur.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know low == high can occur, but I meant that specifically low > high shouldn't ever occur.

Oh, I misunderstood then. I tried to assert! low >= high, not low > high. Then that explains why the tests failed.

core/src/avm1/globals/array.rs Show resolved Hide resolved
@adrian17
Copy link
Collaborator

adrian17 commented Dec 3, 2024

I think it looks good, once you update the PR I can probably quickly test and approve it tomorrow c:

@123jjck 123jjck force-pushed the patch-1 branch 2 times, most recently from bfe95f3 to 2075784 Compare December 3, 2024 22:41
Copy link
Collaborator

@adrian17 adrian17 left a comment

Choose a reason for hiding this comment

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

I don't think that assert is strictly critical, so I think this can go in as-is (let's just squash on merge).

@adrian17 adrian17 enabled auto-merge (squash) December 4, 2024 22:08
@adrian17 adrian17 disabled auto-merge December 4, 2024 22:08
@adrian17 adrian17 enabled auto-merge (squash) December 4, 2024 22:08
@adrian17 adrian17 merged commit 44ebce3 into ruffle-rs:master Dec 4, 2024
21 of 22 checks passed
@adrian17
Copy link
Collaborator

adrian17 commented Dec 4, 2024

Thank you!

@123jjck 123jjck deleted the patch-1 branch December 5, 2024 05:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-avm1 Area: AVM1 (ActionScript 1 & 2) T-perf Type: Performance Improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[AS2] Array.sortOn: Uncaught RangeError: Maximum call stack size exceeded on large arrays
3 participants