From 1cf8ca2c6e57cf8cd9794d5bb6bb4f8b22711560 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 4 Jul 2019 03:49:51 +0000 Subject: http: use gperf for common fields optimization GNU gperf is a commonly-used tool for generating perfect hashes and available on every platform unicorn runs on. C Ruby, gcc, glibc all already use it. Using a hash lookup instead of a linear scan already shows measurable improvements when memoized header keys are all used: * test/benchmark/http_parser.rb (no options): 100000 iterations user system total real - 0.411857 0.000200 0.412057 ( 0.412070) + 0.397960 0.000181 0.398141 ( 0.398149) Results which require generating a new string from an unmemoized header is less significant, but still consistent measurable: * test/benchmark/http_parser.rb -H 'DNT: 1' 100000 iterations user system total real - 0.461416 0.000000 0.461416 ( 0.461417) + 0.461329 0.000000 0.461329 ( 0.461363) Most importantly, this change allows us to memoize more keys without worrying too much about the overhead of a O(n) scan. --- ext/unicorn_http/common_fields.gperf | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 ext/unicorn_http/common_fields.gperf (limited to 'ext/unicorn_http/common_fields.gperf') diff --git a/ext/unicorn_http/common_fields.gperf b/ext/unicorn_http/common_fields.gperf new file mode 100644 index 0000000..179afe5 --- /dev/null +++ b/ext/unicorn_http/common_fields.gperf @@ -0,0 +1,56 @@ +%{ +#include +%} +%compare-lengths +%enum +%global-table +%language=ANSI-C +%pic +%struct-type +%define hash-function-name cf_hash +%define length-table-name cf_lengthtable +%define lookup-function-name cf_lookup +%define string-pool-name cf_stringpool +%define word-array-name cf_wordlist + +struct common_field { size_t name; VALUE value; }; +%% +ACCEPT +ACCEPT_CHARSET +ACCEPT_ENCODING +ACCEPT_LANGUAGE +ALLOW +AUTHORIZATION +CACHE_CONTROL +CONNECTION +CONTENT_ENCODING +CONTENT_LENGTH +CONTENT_TYPE +COOKIE +DATE +EXPECT +FROM +HOST +IF_MATCH +IF_MODIFIED_SINCE +IF_NONE_MATCH +IF_RANGE +IF_UNMODIFIED_SINCE +# Firefox sends Keep-Alive (or maybe only old versions?) +KEEP_ALIVE +MAX_FORWARDS +PRAGMA +PROXY_AUTHORIZATION +RANGE +REFERER +TE +TRAILER +TRANSFER_ENCODING +UPGRADE +USER_AGENT +VIA +# common proxies set some of these X- headers +X_FORWARDED_FOR +X_FORWARDED_PROTO +X_REAL_IP +WARNING -- cgit v1.2.3-24-ge0c7