Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide a CoW box for large HTTPFrame.FramePayload cases. (apple#110)
Motivation: Anything that passes through a NIO pipeline in high volume that is not special-cased by NIOAny needs to have careful attention paid to its size. This is because if it's more than 3 64-bit words wide (24 bytes), it will need to be heap-allocated to be stuffed into the Any case of the NIOAny. Sadly, HTTP2Frame was 44 bytes wide: altogether too wide for the pipeline. This was forcing heap allocations each time a frame was sent or received in the pipeline, which is not so good. To avoid this problem we normally turn our data structures into a CoW box. We want to do that here as well, but we need to be a bit careful. Many parts of the code access the `streamID` field frequently, and placing the stream ID into the CoW box will slow those accesses down by requiring a memory load from a non-stack location. Additionally, code frequently checks the payload discriminator byte, which we would like out of the box as well if at all possible. It turns out that we have a neat tool at our disposal to achieve this: `indirect case`. This allows us to ask the Swift compiler to box a structure *when stored in an enum case*. The effect is to shrink the size of the enumeration when passed around as an enum, but nonetheless allow the contained objects to be identical in form and API to when they were unboxed. It's very helpful here. This shrinks the size of the HTTP2Frame data structure from 44 bytes to 18 bytes, dropping the size of the payload enumeration to 10 bytes and leading to a 10% perf gain in some microbenchmarks. Modifications: - Placed large HTTP2Frame.FramePayload cases into a box. Result: Performance improvements!
- Loading branch information