Skip to content

Improve Performance of HTTPField.value - #146

Merged
fabianfett merged 15 commits into
apple:mainfrom
nerdsupremacist:mq-field-value-perf
Aug 31, 2026
Merged

Improve Performance of HTTPField.value#146
fabianfett merged 15 commits into
apple:mainfrom
nerdsupremacist:mq-field-value-perf

Conversation

@nerdsupremacist

@nerdsupremacist nerdsupremacist commented Aug 28, 2026

Copy link
Copy Markdown
Member

Motivation

When instantiating new HTTPFields, the values need to be validated, legalized and turned into the internal representation.
We use this representation to expose a string in HTTPField.value as well as to iterate over raw bytes using HTTPField.withUnsafeBytesOfValue.

Currently the internal representation is to use a ISO Latin 1 String to store the bytes only once. This however means that we need to transcode back and forth for non ascii values, which causes a lot of extra computations and allocations.

Modifications

  1. Moved logic to a standalone structure for HTTPField.Value rather than ISOLatin1String
  2. Added Unit Tests and Benchmarks
  3. Swapped internal storage of values to be an enum of either a string or a value
  4. Whenever the bytes stored are valid utf8, we will not always store the value as a raw string. This means that we need the least amount of allocations and transcoding when operating with the value through our public API
  5. We only store a raw array of bytes whenever the bytes are not valid utf8. This speeds up withUnsafeBytesOfValue massively and HTTPField.value a little bit
  6. During legalization, store the modified bytes in a temporary buffer instead of using lazy collections to avoid allocating an array and speed up utf8 validation
  7. Use spans whenever possible to speed up access to bytes without boundary checks

Result

These are the changes on the benchmarks added in this PR

HTTPField-asciiBytesValueRoundTrip
Instructions: 28K -> 6847 (-75%)
Malloc: 1 -> 1

HTTPField-asciiValueRoundTrip
Instructions: 7367 -> 3081 (-58%)
Malloc: 0 -> 0

HTTPField-invalidAsciiBytesValueRoundTrip
Instructions: 133K -> 7255 (-94%)
Malloc: 6 -> 1 (-83%)

HTTPField-invalidAsciiBytesValueRoundTripAsLenientValue
Instructions: 62K -> 6623 (-89%)
Malloc: 3 -> 1 (-66%)

HTTPField-invalidAsciiValueRoundTrip
Instructions: 93K -> 6959 (-92%)
Malloc: 5 -> 1 (-80%)

HTTPField-invalidNonASCIIValueRoundTrip
Instructions: 393K -> 8735 (-97%)
Malloc: 11 -> 1 (-91%)

HTTPField-nonASCIIValueRoundTrip
Instructions: 131K -> 3219 (-97%)
Malloc: 4 -> 0 (-100%)

@fabianfett
fabianfett self-requested a review August 28, 2026 11:42
@nerdsupremacist
nerdsupremacist force-pushed the mq-field-value-perf branch 2 times, most recently from b93e474 to f752f2f Compare August 28, 2026 12:22
fabianfett pushed a commit that referenced this pull request Aug 28, 2026
### Motivation

In #146 we're going to be revamping the internal structure and
implementation of how we store values for http fields. To do it safely,
I want to add a few tests to make sure we do not regress it

### Modifications

Added tests for all the edge cases I could come up with for HTTP Field
Values

### Result

Tests Pass
Comment thread Sources/HTTPTypes/HTTPFieldValue.swift Outdated
@fabianfett fabianfett added the 🔨 semver/patch No public API change. label Aug 31, 2026

@fabianfett fabianfett left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@fabianfett
fabianfett merged commit f41c097 into apple:main Aug 31, 2026
71 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants