Conversation
Curl_raw_toupper() and Curl_raw_tolower() were out-of-line functions doing a single table lookup, and casecompare() invokes one of them twice per byte compared, so every case-insensitive comparison in the library paid two calls per byte: header matching, scheme and host compares, cookie domains. Make them static CURL_INLINE functions in strcase.h and give the two mapping tables external linkage so the lookup inlines in every translation unit without relying on LTO or unity mode. The tables and the mapping they perform are unchanged, so this is not a behavior change. curl_strequal() on identical header names: -49% on a Cortex-A55, -51% on a 250MHz e300c3.
ron-kuper
marked this pull request as ready for review
August 25, 2026 19:16
bagder
approved these changes
Aug 25, 2026
bagder
left a comment
Member
There was a problem hiding this comment.
Nice!
Increased performance at a very small cost. A small and non-intrusive change. I like it!
Member
|
Thanks! |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Curl_raw_toupper()andCurl_raw_tolower()are out-of-line functions whose entire body is one 256-byte table lookup, andcasecompare()invokes one of them twice per byte compared. Every case-insensitive comparison in the library (header matching, scheme and host compares, cookie domains) pays two function calls per byte to do work that could be reduced to a single load.This PR changes them
static CURL_INLINEfunctions instrcase.hand gives the two mapping tables external linkage so the lookup inlines in every translation unit. The tables keep the same bytes and the conversion performs the same mapping, so there is no behavior change: only the linkage of the tables and the placement of the lookup change.Benchmarking
Benchmarking was done using a harness located in https://github.com/ron-kuper/curlbench. Note that his harness covers more of the library than this patch touches (e.g. printf, URL parsing, transfer lifecycle). I am measuring several other candidate changes with it and expect to propose some of them separately. Only the cases in the table above are relevant to this one.
I ran this benchmark on 2 embedded targets that are of interest to me. The results are as follows.
curl_strequal, identical header namescurl_strequal, case-folded matchcurl_strequal, late mismatchcurl_strnequalprefix matchThere is a margin of error in these results caused by 2 kinds of "noise". Repeat noise is when running the same binary run twice yields a different answer. In our benchmarking it is 0.12% median on the A55 and 0.18% on the e300c3. Recompile noise is when recompiling the same binary but with non-functioning code changes that merely cause addresses to move around. On the e300c3 it moves unrelated cases by up to 8%.
The performance gains on an x86-64 desktop clock in at about −79% to −81% on the compare cases. However on this machine I've observed that recompile noise can vary the outcome by 24-34% it's hard to make an apples-to-apples comparison.
Testing
make -C tests nonflaky-teston this patch alone, built--enable-debug --enable-warnings --with-openssl --with-nghttp2 --with-zlib:1734 of 1734 OK, no new compiler warnings.
Includes 1397 (
Curl_cert_hostcheck, which exercises the case compares), 1395, 1396, 1398, 1399, 1502 and 1506.scripts/checksrc.plclean.AI disclosure
I used an AI assistant on this work: for auditing the call sites, for the codegen and object-size checks quoted above, and for parts of the benchmark harness. The change, the reasoning and the measurements are mine, and I have
verified every claim above myself rather than taking them on trust.