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

Improve hit test performance by optimizing Y axis #177

Merged
merged 3 commits into from Jan 19, 2024

Conversation

NickEntin
Copy link
Collaborator

@NickEntin NickEntin commented Jan 4, 2024

This is the first performance optimization for hit test snapshotting, focused on optimizing the Y axis.

Note this optimization introduces a possibility of missing a hit region, specifically in the case where there's a very thin horizontal hit region (for example, a hairline separator view) with the same hit target view on both sides. I think given the huge performance improvement, this is probably acceptable in most cases, but I made it configurable so it's up to consumers to make that trade-off.

Split into three commits:

  1. A pure refactor to make it clearer what the performance optimization does.
  2. Introduces the performance optimization.
  3. Makes the performance optimization configurable.

@@ -11,7 +11,7 @@
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>48.792810</real>
<real>17.200000</real>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This brings the run time to almost (1 / scale factor), so in this case around a 65% improvement for a 3x device over the original implementation in #119.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Increasing the maxPermissibleMissedRegionHeight to larger values continues to improve the run time, but you get diminishing returns.

2 => 10.259 sec
4 => 8.317 sec

// error, in particular when dealing with bounds with a negative y origin. By striding to a value slightly
// less than the desired stop (small enough to be less than the density of any screen in the foreseeable
// future), we can avoid this rounding problem.
let stopEpsilon: CGFloat = 0.0001
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we ever see screens with density high enough that this is an issue, I will eat my futuristic hat

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe by the iPhone C

}

} else {
// No-op. We'll draw this on the next iteration.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice

Base automatically changed from entin/hit-test-snapshot to master January 19, 2024 00:57
@NickEntin NickEntin merged commit e0274b2 into master Jan 19, 2024
6 checks passed
@NickEntin NickEntin deleted the entin/hit-test-snapshot-performance branch January 19, 2024 00:58
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.

None yet

2 participants