Skip to content

Commit 0ad7ff6

Browse files
authored
Use unchecked math in encodeInteger (#328)
Motivation Checked math is great when you aren't sure what the constraints are, but in some places we happen to know that all the arithmetic operations occur in a defined domain and range. In those cases, we can improve the codegen by adopting unchecked math. Modifications Widely adopt unchecked math in encodeInteger. Result Better codegen for encodeInteger.
1 parent 344e118 commit 0ad7ff6

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

Sources/NIOHPACK/IntegerCoding.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ func encodeInteger(_ value: UInt, to buffer: inout ByteBuffer,
3131

3232
let start = buffer.writerIndex
3333

34-
let k = (1 << prefix) - 1
34+
// The prefix is always hard-coded, and must fit within 8, so unchecked math here is definitely safe.
35+
let k = (1 &<< prefix) &- 1
3536
var initialByte = prefixBits
3637

3738
if value < k {
@@ -48,15 +49,17 @@ func encodeInteger(_ value: UInt, to buffer: inout ByteBuffer,
4849

4950
// deduct the initial [prefix] bits from the value, then encode it seven bits at a time into
5051
// the remaining bytes.
51-
var n = value - UInt(k)
52+
// We can safely use unchecked subtraction here: we know that `k` is zero or greater, and that `value` is
53+
// either the same value or greater. As a result, this can be unchecked: it's always safe.
54+
var n = value &- UInt(k)
5255
while n >= 128 {
53-
let nextByte = (1 << 7) | UInt8(n & 0x7f)
56+
let nextByte = (1 << 7) | UInt8(truncatingIfNeeded: n & 0x7f)
5457
buffer.writeInteger(nextByte)
5558
n >>= 7
5659
}
5760

58-
buffer.writeInteger(UInt8(n))
59-
return buffer.writerIndex - start
61+
buffer.writeInteger(UInt8(truncatingIfNeeded: n))
62+
return buffer.writerIndex &- start
6063
}
6164

6265
fileprivate let valueMask: UInt8 = 127

0 commit comments

Comments
 (0)