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

Speed up the ContainExactly matcher #1333

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

bclayman-sq
Copy link
Contributor

@bclayman-sq bclayman-sq commented Oct 29, 2021

Speed up the ContainExactly matcher by pre-emptively matching up corresponding elements in the expected and actual arrays.

This addresses issues #1006, #1161.

Before this PR, comparing two arrays of 50 random integers never finished. Now, comparing arrays of 10,000 random integers takes 1 second.

This PR is a collaboration between @genehsu and I based on a couple of our earlier PRs and discussion that resulted:

  1. Improve ContainExactly matcher speed when elements obey transitivity #1325
  2. Speed up the ContainExactly matcher #1328

Co-authored-by: Gene Hsu [email protected]

@bclayman-sq
Copy link
Contributor Author

@genehsu, Could I get your email so I can update the "co-authored-by" section of the PR description?

@JonRowe
Copy link
Member

JonRowe commented Oct 29, 2021

If this superseeds the other PR(s) can you close it/them? Will help with the review backlog which is currently sitting at 25 tabs

@bclayman-sq bclayman-sq force-pushed the bclayman-genehsu/improve-contains-exactly-speed branch from 96ba1da to 7972abf Compare October 29, 2021 17:35
@bclayman-sq
Copy link
Contributor Author

If this superseeds the other PR(s) can you close it/them? Will help with the review backlog which is currently sitting at 25 tabs

Yeah, I'm happy to! Mostly wanted to be sure Gene was satisfied with this outcome and I wasn't stepping on any toes, so I'll wait for them to comment before closing 👍

Speed up the ContainExactly matcher by pre-emptively matching up corresponding elements in the expected and actual arrays.

This addresses rspec#1006, rspec#1161.

This PR is a collaboration between me and @genehsu based on
a couple of our earlier PRs and discussion that resulted:
1) rspec#1325
2) rspec#1328

Co-authored-by: Gene Hsu (@genehsu)
@bclayman-sq bclayman-sq force-pushed the bclayman-genehsu/improve-contains-exactly-speed branch from 7972abf to 56ba3e4 Compare October 29, 2021 18:19
@genehsu
Copy link

genehsu commented Oct 29, 2021

@bclayman-sq

Looks good. I'd suggest that 1000 random elements should be enough since we're hitting timing issues on one of the Jruby test suites.

@genehsu, Could I get your email so I can update the "co-authored-by" section of the PR description?

gene at hsufarm dot com

I'm closing my previous PR now

@bclayman-sq
Copy link
Contributor Author

bclayman-sq commented Oct 29, 2021

@bclayman-sq

Looks good. I'd suggest that 1000 random elements should be enough since we're hitting timing issues on one of the Jruby test suites.

@genehsu, Could I get your email so I can update the "co-authored-by" section of the PR description?

gene at hsufarm dot com

I'm closing my previous PR now

Ah gotcha, I ended up bumping to 2s to get around that pesky jruby one but agree in general that 1000 is probably plenty 👍

Sounds good, will update the PR description and close my earlier PR!

Comment on lines 214 to 215
let(:max_runtime) { 2 }
let(:actual) { Array.new(10_000) { rand(10) } }
Copy link

Choose a reason for hiding this comment

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

Suggestion: 1000 elements should be enough to see if the algorithm update works well. Then max_runtime can be dialed down as well, maybe back to 0.5.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah sure thing, just updated to 1K elements and 0.5s timeout 👍

Copy link
Member

@JonRowe JonRowe left a comment

Choose a reason for hiding this comment

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

Great work, can we get a benchmark of the old implementation vs the new implementation added as a comment above the implementation to explain why its so complex, plus I have some wording tweaks for the tests as suggestion, especially the subject bit as we prefer named subjects where possible.

spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
it do
timeout_if_not_debugging(max_runtime) do
expect {
subject
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
subject
expect_actual_to_contain_exactly_expected

Copy link
Member

Choose a reason for hiding this comment

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

subject is a substitute for expect_actual_to_contain_exactly_expected or expect_actual_not_to_contain_exactly_expected depending on the including example group.

spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
spec/rspec/matchers/built_in/contain_exactly_spec.rb Outdated Show resolved Hide resolved
@bclayman-sq
Copy link
Contributor Author

bclayman-sq commented Nov 6, 2021

Great work, can we get a benchmark of the old implementation vs the new implementation added as a comment above the implementation to explain why its so complex, plus I have some wording tweaks for the tests as suggestion, especially the subject bit as we prefer named subjects where possible.

Of course! This is really helpful feedback; I just:

  1. Added a comment with benchmark data to justify the complexity
  2. Incorporated the wording tweaks
  3. Added named subjects where possible

One note on 3.: I didn't change the shared examples to use a named subject like expect_actual_to_contain_exactly_expected instead of subject. The specs use shared examples for both positive and negative expectations, so changing either shared example to use expect_actual_to_contain_exactly_expected or expect_actual_not_to_contain_exactly_expected wouldn't exercise the behavior we want and would cause a couple failing tests. Relying on subject in both shared examples lets me override it as appropriate in the context for a positive expectation and the context for a negative expectation.

Let me know if I've misunderstood anything here and thanks for the review!

Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

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

Fantastic job! Thank you

@bclayman-sq
Copy link
Contributor Author

@JonRowe @pirj Hi, hope you two are doing well! I've added a comment with benchmark data per Jon's request and wanted to see if there was anything I could do to get this PR merged in. Let me know!

(I have a couple other PRs from several months ago that I'll comment on similarly!)

@bclayman-sq
Copy link
Contributor Author

bclayman-sq commented Apr 25, 2022

@JonRowe @pirj Hi, hope you two are doing well! I've added a comment with benchmark data per Jon's request and wanted to see if there was anything I could do to get this PR merged in. Let me know!

(I have a couple other PRs from several months ago that I'll comment on similarly!)

👋 Hi @JonRowe, @pirj has approved this and I've managed to incorporate your requested changes (benchmark data, wording tweaks). I followed up a month or so ago and imagine you're slammed. I do still want to get this in, however! Would you feel OK merging this?

If it helps, I'm happy to review a pending PR or two to lighten the load on the core reviewers 👍 Appreciate your help as always!

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