-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Performance improvements for reading keypaths #70451
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
Conversation
@swift-ci please smoke test |
@swift-ci please benchmark |
@swift-ci please benchmark Apple Silicon |
@swift-ci please smoke test |
@swift-ci please benchmark Apple Silicon |
@swift-ci please benchmark |
@swift-ci please smoke test |
@swift-ci please benchmark |
@swift-ci please test |
@swift-ci please build macOS toolchain |
@phausler Should it be "please build toolchain macOS"? Or just "please build toolchain"? I'm not seeing anything in the CI queue. |
@swift-ci please build toolchain |
@swift-ci build toolchain |
@stephencelis sorry for the late reply, I tried out the code snippet you linked with this change and it still crashes at runtime. I think this is the compiler doing something incorrectly perhaps, but maybe it's in the keypath appending logic. I'll take a closer look. |
e381555
to
3b0a35d
Compare
@swift-ci please test |
3b0a35d
to
1ca08c1
Compare
@swift-ci please test |
1ca08c1
to
1f949a5
Compare
@swift-ci please test |
@swift-ci please benchmark Apple silicon |
@swift-ci please test |
@swift-ci please benchmark |
@swift-ci please test |
@swift-ci please benchmark |
@swift-ci Please Build Toolchain macOS Platform |
c0571a5
to
90bd2a0
Compare
@swift-ci please test |
@swift-ci please benchmark |
@swift-ci please test |
@swift-ci please benchmark |
Performance (x86_64): -O
|
if _fastPath(tag == 0) { | ||
// Optional "shares" a layout with its Wrapped type meaning we can | ||
// reinterpret the base address as an address to its Wrapped value. | ||
pointer.initialize(to: Builtin.reinterpretCast(base)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we ensure the tag byte, if any, after the base value is zero?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand what you mean here 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Optional<T>
is larger than T
(because T doesn't have any extra inhabitants) then the tag byte after the payload needs to be zero to indicate the some
case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I check that right before this:
// Optional's tags are some = 0, none = 1
let tag = UInt32(Builtin.getEnumTag(base))
I call the vwt to get the enum tag of the value and if it's 0 then I know I can bit cast the optional value to its wrapped one.
This patch includes some performance improvements for reading out a value from a key path. Essentially I've cut out all metadata allocations within the projection loop as well as getting rid of the intermediate
Any
value we were using to traffic intermediate values. Instead, we calculate the largest type we'll ever store during instantiation and stuff that value at the end of the buffer. We'll read this value when we project and create a temporary allocation and constantly re-view this memory for components.Partially resolves: rdar://116587442