forked from apple/swift-nio
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement faster pointer rebasing. (apple#1696)
Motivation: I recently discovered that UnsafeRawBufferPointer.init(rebasing:) is surprisingly expensive, with 7 traps and 11 branches. A simple replacement can make it a lot cheaper, down to two traps and four branches. This ends up having pretty drastic effects on ByteBuffer-heavy NIO code, which often outlines the call to that initializer and loses the ability to make a bunch of site-local optimisations. While this has been potentially fixed upstream with apple/swift#34879, there is no good reason to wait until Swift 5.4 for this improvement. Due to the niche use-case, I didn't bother doing this for _every_ rebasing in the program. In particular, there is at least one UnsafeBufferPointer(rebasing:) that I didn't do this with, and there are uses in both NIOTLS and NIOHTTP1 that I didn't change. While we can fix those if we really need to, it would be nice to avoid this helper proliferating too far through our codebase. Modifications: - Replaced the use of URBP.init(rebasing:) with a custom hand-rolled version that avoids Slice.count. Result: Cheaper code. One NIOHTTP2 benchmark sees a 2.9% speedup from this change alone.
- Loading branch information
Showing
5 changed files
with
56 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the SwiftNIO open source project | ||
// | ||
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// MARK: Rebasing shims | ||
|
||
// These methods are shimmed in to NIO until https://github.com/apple/swift/pull/34879 is resolved. | ||
// They address the fact that the current rebasing initializers are surprisingly expensive and do excessive | ||
// checked arithmetic. This expense forces them to often be outlined, reducing the ability to optimise out | ||
// further preconditions and branches. | ||
extension UnsafeRawBufferPointer { | ||
@inlinable | ||
init(fastRebase slice: Slice<UnsafeRawBufferPointer>) { | ||
let base = slice.base.baseAddress?.advanced(by: slice.startIndex) | ||
self.init(start: base, count: slice.endIndex &- slice.startIndex) | ||
} | ||
|
||
@inlinable | ||
init(fastRebase slice: Slice<UnsafeMutableRawBufferPointer>) { | ||
let base = slice.base.baseAddress?.advanced(by: slice.startIndex) | ||
self.init(start: base, count: slice.endIndex &- slice.startIndex) | ||
} | ||
} | ||
|
||
extension UnsafeMutableRawBufferPointer { | ||
@inlinable | ||
init(fastRebase slice: Slice<UnsafeMutableRawBufferPointer>) { | ||
let base = slice.base.baseAddress?.advanced(by: slice.startIndex) | ||
self.init(start: base, count: slice.endIndex &- slice.startIndex) | ||
} | ||
} |