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

Reduce overhead of .expectationChecked event handling in #expect(). #610

Merged

Conversation

grynspan
Copy link
Contributor

@grynspan grynspan commented Aug 12, 2024

This PR refactors the implementation of #expect() and #require() a bit such that they don't incur more than minimal overhead posting .expectationChecked events if nobody is listening for them (which, currently, nobody is.)

We considered removing .expectationChecked outright, but XCTest has historically had a number of requests for a way to observe calls to XCTAssert() etc. even when they pass, so we opted not to remove the event kind at this time.

This PR also introduces a cache for fully-qualified type names so that we don't need to call into the runtime to get them as often.

Overall speedup is approximately 90% or 11x. Test time for a tight loop of 1,000,000 #expect() calls goes from 5.898893 seconds down to 0.515558291 seconds (as measured on my work computer.)

Resolves rdar://133517028.

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

This PR refactors the implementation of `#expect()` and `#require()` a bit such
that they don't incur more than minimal overhead posting `.expectationChecked`
events if nobody is listening for them (which, currently, nobody is.)

We considered removing `.expectationChecked` outright, but XCTest has
historically had a number of requests for a way to observe calls to
`XCTAssert()` etc. even when they pass, so we opted not to remove the event kind
at this time.

This PR also introduces a cache for fully-qualified type names so that we don't
need to call into the runtime to get them as often.

Overall speedup is approximately **90% or 11x**. Test time for a tight loop of
1,000,000 `#expect()` calls goes from 5.898893 seconds down to 0.515558291
seconds (as measured on my work computer.)

Resolves rdar://133517028.
@grynspan grynspan added bug Something isn't working performance Performance issues swift-6.1 labels Aug 12, 2024
@grynspan grynspan self-assigned this Aug 12, 2024
@grynspan
Copy link
Contributor Author

@swift-ci please test

@grynspan
Copy link
Contributor Author

@swift-ci please test

@grynspan
Copy link
Contributor Author

@swift-ci please test

@grynspan grynspan changed the base branch from main to main-next August 21, 2024 00:18
@grynspan grynspan merged commit 8534698 into main-next Aug 21, 2024
3 checks passed
@grynspan grynspan deleted the jgrynspan/133517028-minimize-expectationChecked-overhead branch August 21, 2024 00:18
grynspan added a commit that referenced this pull request Aug 21, 2024
This PR fixes a conflict between #610 and #619. #610 added a string cache to
`TypeInfo` using `ObjectIdentifier` instances as keys. #619 added support for
move-only types to `TypeInfo`. Due to rdar://134276458, move-only types cannot
be used with `ObjectIdentifier`. This PR uses `UInt` instead until that issue
can be resolved in a future stdlib update.
@grynspan grynspan mentioned this pull request Aug 21, 2024
2 tasks
grynspan added a commit that referenced this pull request Aug 21, 2024
This PR fixes a conflict between #610 and #619. #610 added a string
cache to `TypeInfo` using `ObjectIdentifier` instances as keys. #619
added support for move-only types to `TypeInfo`. Due to
rdar://134276458, move-only types cannot be used with
`ObjectIdentifier`. This PR uses `UInt` instead until that issue can be
resolved in a future stdlib update.

### Checklist:

- [x] Code and documentation should follow the style of the [Style
Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md).
- [x] If public symbols are renamed or modified, DocC references should
be updated.
grynspan added a commit that referenced this pull request Sep 3, 2024
…`. (#610)

This PR refactors the implementation of `#expect()` and `#require()` a
bit such that they don't incur more than minimal overhead posting
`.expectationChecked` events if nobody is listening for them (which,
currently, nobody is.)

We considered removing `.expectationChecked` outright, but XCTest has
historically had a number of requests for a way to observe calls to
`XCTAssert()` etc. even when they pass, so we opted not to remove the
event kind at this time.

This PR also introduces a cache for fully-qualified type names so that
we don't need to call into the runtime to get them as often.

Overall speedup is approximately **90% or 11x**. Test time for a tight
loop of 1,000,000 `#expect()` calls goes from 5.898893 seconds down to
0.515558291 seconds (as measured on my work computer.)

Resolves rdar://133517028.

### Checklist:

- [x] Code and documentation should follow the style of the [Style
Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md).
- [x] If public symbols are renamed or modified, DocC references should
be updated.
grynspan added a commit that referenced this pull request Sep 3, 2024
…pect()`. (#657)

**Explanation:** Optimizes the implementation of `#expect()`, in
particular the parts that ask for fully-qualified type names and
generate `.expectationChecked` events.
**Scope:** 6.0 branch
**Issue:** N/A
**Original PR:** #610
**Risk:** Moderate—refactors code inside `#expect()` and introduces a
new lock and atomic value used by them.
**Testing:** New unit test coverage, existing coverage.
**Reviewer:** @briancroom @suzannaratcliff
grynspan added a commit that referenced this pull request Sep 4, 2024
…pect()`. (#657)

**Explanation:** Optimizes the implementation of `#expect()`, in
particular the parts that ask for fully-qualified type names and
generate `.expectationChecked` events.
**Scope:** 6.0 branch
**Issue:** N/A
**Original PR:** #610
**Risk:** Moderate—refactors code inside `#expect()` and introduces a
new lock and atomic value used by them.
**Testing:** New unit test coverage, existing coverage.
**Reviewer:** @briancroom @suzannaratcliff
grynspan added a commit that referenced this pull request Sep 4, 2024
…pect()` (take 2) (#659)

**Explanation:** Optimizes the implementation of `#expect()`, in
particular the parts that ask for fully-qualified type names and
generate `.expectationChecked` events.
**Scope:** 6.0 branch
**Issue:** N/A
**Original PR:** #610,
also includes fixup commit 6ba948a
**Risk:** Moderate—refactors code inside `#expect()` and introduces a
new lock and atomic value used by them.
**Testing:** New unit test coverage, existing coverage.
**Reviewer:** @briancroom @suzannaratcliff
@grynspan grynspan added this to the Swift 6.1 milestone Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working performance Performance issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants