sfeed

Simple RSS and Atom feed parser
git clone https://git.sinitax.com/codemadness/sfeed
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

commit 91f51eb809e13021cef3342b2688dc354c3f9c9e
parent 5a3995ae274b7fa19823a5fae72afe1c493a4c44
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Sat,  6 Apr 2019 14:58:37 +0200

optimization: define GETNEXT as an inline macro

This reduces much function call overhead. getnext is defined in xml.h for
inline optimization. sfeed only uses one XML parser context per program, this
allows further optimizations of the compiler also.

On OpenBSD it was noticable because of retpoline etc function call overhead.
Using clang and a 500MB test XML file reduces processing time from +- 12s to
5s.

Tested using some crazy optimization flags:
SFEED_CFLAGS = -O3 -std=c99 -DGETNEXT=getchar_unlocked -fno-ret-protector \
	-mno-retpoline -static

A GETNEXT macro is also nice for programs which mmap(2) some big XML file. Then
you can simply define:

	#define GETNEXT() (off >= len ? EOF : reg[off++])

Diffstat:
Msfeed.c | 2+-
Msfeed_opml_import.c | 2+-
Msfeed_web.c | 2+-
Msfeed_xmlenc.c | 2+-
Mxml.h | 9+++++++--
5 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/sfeed.c b/sfeed.c @@ -878,7 +878,7 @@ main(int argc, char *argv[]) parser.xmltagstart = xmltagstart; parser.xmltagstartparsed = xmltagstartparsed; - parser.getnext = getchar; + /* NOTE: getnext is defined in xml.h for inline optimization */ xml_parse(&parser); return 0; diff --git a/sfeed_opml_import.c b/sfeed_opml_import.c @@ -97,7 +97,7 @@ main(void) "# list of feeds to fetch:\n" "feeds() {\n" " # feed <name> <feedurl> [basesiteurl] [encoding]\n", stdout); - parser.getnext = getchar; + /* NOTE: getnext is defined in xml.h for inline optimization */ xml_parse(&parser); fputs("}\n", stdout); diff --git a/sfeed_web.c b/sfeed_web.c @@ -92,7 +92,7 @@ main(int argc, char *argv[]) parser.xmltagstart = xmltagstart; parser.xmltagstartparsed = xmltagstartparsed; - parser.getnext = getchar; + /* NOTE: getnext is defined in xml.h for inline optimization */ xml_parse(&parser); return found > 0 ? 0 : 1; diff --git a/sfeed_xmlenc.c b/sfeed_xmlenc.c @@ -47,7 +47,7 @@ main(void) parser.xmlattr = xmlattr; parser.xmltagstart = xmltagstart; - parser.getnext = getchar; + /* NOTE: getnext is defined in xml.h for inline optimization */ xml_parse(&parser); return 0; diff --git a/xml.h b/xml.h @@ -27,9 +27,14 @@ typedef struct xmlparser { size_t, int); #ifndef GETNEXT -#define GETNEXT (x)->getnext -#endif + /* GETNEXT overridden for sfeed to reduce function call overhead and + further context optimizations. */ + #define GETNEXT getchar +#if 0 + #define GETNEXT (x)->getnext int (*getnext)(void); +#endif +#endif /* current tag */ char tag[1024];