Skip to content

Commit aee724f

Browse files
committed
perf(decoder): @inline(__always) on decodeFixedWidthInteger helpers
A direct BEFORE/AFTER benchmark on Apple M2 Pro caught the generic helpers added in c4531f3 introducing a +5% mean regression on numeric- heavy decode paths (e.g. `Decode 100K rows (numeric fields)` +6.4%, `Decode 100K rows (simple)` +5.2%). The compiler wasn't fully specialising the `<T: FixedWidthInteger>` generic across all nine call sites without the hint. Adding `@inline(__always)` to both helpers collapses the regression to within run-to-run noise (≤+2% on remaining cases, several scenarios actually faster than the pre-refactor baseline): Decode 100K rows (simple) 153.05 → 154.51 ms +0.95% Decode 100K rows (numeric) 157.27 → 159.82 ms +1.62% Decode 100K transactions 501.64 → 498.26 ms -0.67% Decode 100K log entries 490.61 → 489.19 ms -0.29% Encode 100K rows 129.09 → 125.28 ms -2.95% Encode 10K rows (quoted) 11.92 → 11.71 ms -1.76% Encode 100K rows to String 127.37 → 124.69 ms -2.10% Mixed: Decode+Transform+Encode 29.15 → 28.73 ms -1.43% 305/305 tests pass.
1 parent 58a8e12 commit aee724f

2 files changed

Lines changed: 10 additions & 0 deletions

File tree

Sources/CSVCoder/Decoder/CSVRowDecoder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@ struct CSVKeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContainerProtocol
486486
/// the field as `Int64`, then narrows via `T(exactly:)`. The type name
487487
/// in the diagnostic comes from `T` itself so adding a new integer
488488
/// width never drifts from the error message.
489+
///
490+
/// `@inline(__always)` is required: without it the bench measured a
491+
/// +5% regression on numeric-heavy decode paths because the generic
492+
/// helper wasn't fully specialised through all nine call sites.
493+
@inline(__always)
489494
private func decodeFixedWidthInteger<T: FixedWidthInteger>(
490495
_ type: T.Type,
491496
forKey key: Key

Sources/CSVCoder/Decoder/CSVSingleValueDecoder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ struct CSVSingleValueContainer: SingleValueDecodingContainer {
160160
/// the trimmed field as `Int64`, then narrows via `T(exactly:)`. The
161161
/// type name in the diagnostic comes from `T` itself so adding a new
162162
/// integer width never drifts from the error message.
163+
///
164+
/// `@inline(__always)` is required: without it the bench measured a
165+
/// +5% regression on numeric-heavy decode paths because the generic
166+
/// helper wasn't fully specialised through all nine call sites.
167+
@inline(__always)
163168
private func decodeFixedWidthInteger<T: FixedWidthInteger>(_ type: T.Type) throws -> T {
164169
guard let raw = CSVValueParser.parseInt64(trimmedValue, strategy: configuration.numberDecodingStrategy),
165170
let result = T(exactly: raw)

0 commit comments

Comments
 (0)