-
Notifications
You must be signed in to change notification settings - Fork 84
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
Make HPACKHeaders inlinable. #269
Conversation
Motivation: HPACKHeaders is a trivial data structure (a wrapper around Array) that is present in the public API of all NIO HTTP/2 programs. This makes it a tempting target for adding inlinable calls, primarily as a way to drive down ARC. The fact that strings frequently travel across the API boundary means that otherwise innocuous use-cases can trigger unexpected ARC traffic. Making as much of the implementation inlinable as possible reduces a lot of this overhead and opens up the possibility for better performance in a number of parts of the code, including in the core HTTP/2 protocol engine, which operates extensively on this data type. Modifications: - Make basically everything inlinable. Result: Our benchmarks are about 0.7% faster.
efa07d5
to
6d48cdc
Compare
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.
Generally looks good but I've made a couple of comments.
@inline(never) | ||
private func _compareCaseInsensitiveASCIIBytesSlowPath(to other: String.UTF8View) -> Bool { | ||
func _compareCaseInsensitiveASCIIBytesSlowPath(to other: String.UTF8View) -> Bool { |
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.
This looks odd - inlineable but never?
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.
Yup. This is a logically sensible stanza. @inlinable
means the definition is available to the compiler when compiling the module using the code. This allows, for example, specialization. But the method may not be inlined. In this case the primary use is to let the compiler see through the call and observe that we never write to any memory here.
@@ -461,7 +502,8 @@ extension String.UTF8View { | |||
/// | |||
/// - Parameter bytes: The string constant in the form of a collection of `UInt8` | |||
/// - Returns: Whether the collection contains **EXACTLY** this array or no, but by ignoring case. | |||
fileprivate func compareCaseInsensitiveASCIIBytes(to other: String.UTF8View) -> Bool { | |||
@inlinable |
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.
I've not read the rules but I don't see any logical reason why something shouldn't be both inlineable and fileprivate.
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.
Totally reasonable except that the rule is it has to be internal
or higher.
Motivation:
HPACKHeaders is a trivial data structure (a wrapper around Array) that
is present in the public API of all NIO HTTP/2 programs. This makes it a
tempting target for adding inlinable calls, primarily as a way to drive
down ARC. The fact that strings frequently travel across the API
boundary means that otherwise innocuous use-cases can trigger unexpected
ARC traffic.
Making as much of the implementation inlinable as possible reduces a lot
of this overhead and opens up the possibility for better performance in
a number of parts of the code, including in the core HTTP/2 protocol
engine, which operates extensively on this data type.
Modifications:
Result:
Our benchmarks are about 0.7% faster.