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. --- GNUmakefile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'GNUmakefile') diff --git a/GNUmakefile b/GNUmakefile index a7e4102..3dbad2c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -10,6 +10,7 @@ RAGEL = ragel RSYNC = rsync OLDDOC = olddoc RDOC = rdoc +GPERF = gperf GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE @./GIT-VERSION-GEN @@ -40,7 +41,9 @@ T_n_log := $(subst .n,$(log_suffix),$(T_n)) test_prefix = $(CURDIR)/test/$(RUBY_ENGINE)-$(RUBY_VERSION) ext := ext/unicorn_http -c_files := $(ext)/unicorn_http.c $(ext)/httpdate.c $(wildcard $(ext)/*.h) +c_files := $(addprefix $(ext)/, unicorn_http.c common_fields.h \ + httpdate.c common_field_optimization.h ext_help.h \ + global_variables.h) rl_files := $(wildcard $(ext)/*.rl) base_bins := unicorn unicorn_rails bins := $(addprefix bin/, $(base_bins)) @@ -48,7 +51,14 @@ man1_rdoc := $(addsuffix _1, $(base_bins)) man1_bins := $(addsuffix .1, $(base_bins)) man1_paths := $(addprefix man/man1/, $(man1_bins)) rb_files := $(bins) $(shell find lib ext -type f -name '*.rb') -inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb +inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb \ + $(ext)/common_fields.gperf + +gperf :: $(ext)/common_fields.h +$(ext)/common_fields.h : $(ext)/common_fields.gperf $(ext)/gperf.rb + $(GPERF) $< >$@- + $(MRI) --disable-gems $(ext)/gperf.rb <$@- >$@+ + test -s $@+ && mv $@+ $@ && $(RM) $@- ragel: $(ext)/unicorn_http.c $(ext)/unicorn_http.c: $(rl_files) @@ -159,12 +169,12 @@ man html: $(MAKE) -C Documentation install-$@ pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb LATEST NEWS \ - $(ext)/unicorn_http.c $(man1_paths) + $(ext)/unicorn_http.c $(ext)/common_fields.h $(man1_paths) NEWS: $(OLDDOC) prepare -.manifest: $(ext)/unicorn_http.c man NEWS +.manifest: $(ext)/unicorn_http.c $(ext)/common_fields.h man NEWS (git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \ LC_ALL=C sort > $@+ cmp $@+ $@ || mv $@+ $@ -- cgit v1.2.3-24-ge0c7