From 5399893617ebc52bba1976e94c9f1cc742fff48d Mon Sep 17 00:00:00 2001 From: Yorhel Date: Tue, 3 Sep 2013 09:42:31 +0200 Subject: Add benchmark code --- bench/.gitignore | 5 +++ bench/Makefile | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ bench/bench.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ bench/runbench.sh | 22 +++++++++ 4 files changed, 280 insertions(+) create mode 100644 bench/.gitignore create mode 100644 bench/Makefile create mode 100644 bench/bench.c create mode 100755 bench/runbench.sh diff --git a/bench/.gitignore b/bench/.gitignore new file mode 100644 index 0000000..4d8fd6b --- /dev/null +++ b/bench/.gitignore @@ -0,0 +1,5 @@ +* +!.gitignore +!Makefile +!bench.c +!runbench.sh diff --git a/bench/Makefile b/bench/Makefile new file mode 100644 index 0000000..de5cf42 --- /dev/null +++ b/bench/Makefile @@ -0,0 +1,132 @@ +# The tests are compiled and linked using musl-cross. The advantage of this is +# that everything is self-contained and thus easy to reproduce. Musl is also +# designed for static linking with little overhead, which gives us a good +# metric for the "complete package" of a statically linked minimal XML reader +# for each lib. + +FILE1=enwiki-20130805-abstract5.xml +FILE1URL=http://dumps.wikimedia.org/enwiki/20130805/enwiki-20130805-abstract5.xml +FILE2=discogs_20130801_labels.xml +FILE2URL=http://www.discogs.com/data/${FILE2}.gz +FILES=${FILE1} ${FILE2} +MUSLCROSS=x86_64-linux-musl +MUSLCROSSURL=https://bitbucket.org/GregorR/musl-cross/downloads/crossx86-x86_64-linux-musl-0.9.11.tar.xz +EXPAT=expat-2.1.0 +EXPATURL=http://downloads.sourceforge.net/project/expat/expat/2.1.0/${EXPAT}.tar.gz +LIBXML2=libxml2-2.9.1 +LIBXML2URL=ftp://xmlsoft.org/libxml2/${LIBXML2}.tar.gz +MXML=mxml-2.7 +MXMLURL=http://www.msweet.org/files/project3/${MXML}.tar.gz + +HOST=x86_64-musl-linux +CC=${HOST}-gcc +AR=${HOST}-ar +STRIP=${HOST}-strip +export CFLAGS = -static -O2 +export PATH := ${PATH}:${PWD}/${MUSLCROSS}/bin + +.PHONY: notice all clean distclean + +notice: + @echo "You probably don't want to 'make' these benchmarks." + @echo "Lots of stuff is downloaded, lots of stuff is compiled and lots of stuff is run." + @echo "Run 'make all -j1' if you do have the patience to run the benchmarks." + @echo + @false + +build: strlen yxml expat libxml2 mxml +all: strlen-bench yxml-bench expat-bench libxml2-bench mxml-bench + +${FILE1}: + curl ${FILE1URL} -O ${FILE1} + +${FILE2}: + @echo "This doesn't work. Probably want to download the file manually with a browser" + curl ${FILE2URL} | zcat > ${FILE2} + +${MUSLCROSS}: + curl -L ${MUSLCROSSURL} | xzcat | tar -xvf- + +${EXPAT}: + curl -L ${EXPATURL} | zcat | tar -xvf- + +${LIBXML2}: + curl ${LIBXML2URL} | zcat | tar -xvf- + +${MXML}: + curl ${MXMLURL} | zcat | tar -xvf- + + + +yxml.o: ../yxml.c + make -C .. yxml.c + ${CC} ${CFLAGS} -I.. ../yxml.c -c + +yxml: ${MUSLCROSS} bench.c yxml.o + ${CC} ${CFLAGS} -I.. -DYXML bench.c yxml.o -o yxml + ${STRIP} -s yxml + +yxml-bench: yxml ${FILES} + ./runbench.sh yxml.o yxml ${FILES} + + + +strlen: ${MUSLCROSS} bench.c + ${CC} ${CFLAGS} -DSTRLEN bench.c -o strlen + ${STRIP} -s strlen + +strlen-bench: strlen ${FILES} + ./runbench.sh strlen strlen ${FILES} + + + +libexpat.a: ${MUSLCROSS} ${EXPAT} + cd ${EXPAT} && ./configure --disable-shared --host=${HOST} && make buildlib + cp ${EXPAT}/.libs/libexpat.a libexpat.a + +expat: libexpat.a bench.c + ${CC} ${CFLAGS} -I${EXPAT}/lib -DEXPAT bench.c -L. -lexpat -o expat + ${STRIP} -s expat + +expat-bench: expat ${FILES} + ./runbench.sh libexpat.a expat ${FILES} + + + +libxml2.a: ${MUSLCROSS} ${LIBXML2} + @# So many options, yet --with-minimum and --without-output don't seem to work + cd ${LIBXML2} && ./configure --disable-shared --without-c14n --without-catalog --without-debug\ + --without-docbook --without-ftp --without-html --without-http --without-iconv --without-iso8859x\ + --without-legacy --without-pattern --without-push --without-regexps --without-sax1\ + --without-schemas --without-schematron --without-threads --without-tree --without-valid\ + --without-writer --without-xinclude --without-xpath --without-xpath --without-modules\ + --without-zlib --without-lzma --host ${HOST} && make libxml2.la + cp ${LIBXML2}/.libs/libxml2.a libxml2.a + +libxml2: libxml2.a bench.c + ${CC} ${CFLAGS} -I${LIBXML2}/include -DLIBXML2 bench.c -L. -lxml2 -o libxml2 + ${STRIP} -s libxml2 + +libxml2-bench: libxml2 ${FILES} + ./runbench.sh libxml2.a libxml2 ${FILES} + + + +libmxml.a: ${MUSLCROSS} ${MXML} + cd ${MXML} && ./configure --disable-shared --disable-threads --host ${HOST} && make libmxml.a + cp ${MXML}/libmxml.a libmxml.a + +mxml: libmxml.a bench.c + ${CC} ${CFLAGS} -I${MXML} -DMXML bench.c -L. -lmxml -o mxml + ${STRIP} -s mxml + +mxml-bench: mxml ${FILES} + ./runbench.sh libmxml.a mxml ${FILES} + + + +clean: + rm -f *.a *.o *-bench yxml strlen expat libxml2 mxml + +distclean: + rm -rf ${MUSLCROSS} ${FILES} ${EXPAT} ${LIBXML2} ${MXML} diff --git a/bench/bench.c b/bench/bench.c new file mode 100644 index 0000000..f354dba --- /dev/null +++ b/bench/bench.c @@ -0,0 +1,121 @@ +/* Copyright (c) 2013 Yoran Heling + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(STRLEN) +static void xmlbench(const char *buf, size_t bufsize) { + size_t l = strlen(buf); + assert(l == bufsize); +} + + +#elif defined(YXML) +#include +static void xmlbench(const char *buf, size_t bufsize) { + yxml_t x[1]; + char *stack = malloc(4096); + yxml_init(x, stack, 4096); + yxml_ret_t r; + do { + r = yxml_parse(x, *buf); + buf++; + } while(*buf && r >= 0 && r != YXML_EOD); + /*printf("t%03lu l%03u b%03lu: %c %d", x->total, x->line, x->byte, *buf, r);*/ + assert(!*buf); +} + + +#elif defined(EXPAT) +#include +static void xmlbench(const char *buf, size_t bufsize) { + XML_Parser p = XML_ParserCreate(NULL); + int r = XML_Parse(p, buf, bufsize, 1); + assert(r != XML_STATUS_ERROR); + XML_ParserFree(p); +} + + +#elif defined(LIBXML2) +#include +static void xmlbench(const char *buf, size_t bufsize) { + xmlTextReaderPtr p = xmlReaderForMemory(buf, bufsize, NULL, NULL, 0); + while(xmlTextReaderRead(p) == 1) + ; + xmlFreeTextReader(p); +} + + +#elif defined(MXML) +#include +static void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data) { + static int i; + /* Only retain the root node, to make sure that we don't get NULL. */ + if(event == MXML_SAX_ELEMENT_OPEN && !i) { + mxmlRetain(node); + i=1; + } +} +static void xmlbench(const char *buf, size_t bufsize) { + mxml_node_t *n = mxmlSAXLoadString(NULL, buf, MXML_NO_CALLBACK, sax_cb, NULL); + assert(n); +} + + +#else +#error No idea what to bench +#endif + + +int main(int argc, char **argv) { + struct stat st; + ssize_t r; + + assert(argc == 2); + r = stat(argv[1], &st); + assert(!r); + + char *buf = malloc(st.st_size+1); + assert(buf); + + int fd = open(argv[1], O_RDONLY); + assert(fd > 0); + + ssize_t rd = read(fd, buf, st.st_size); + assert(rd == st.st_size); + buf[st.st_size] = 0; + close(fd); + + xmlbench(buf, st.st_size); + return 0; +} + +/* vim: set noet sw=4 ts=4: */ diff --git a/bench/runbench.sh b/bench/runbench.sh new file mode 100755 index 0000000..77b4e50 --- /dev/null +++ b/bench/runbench.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +OBJ=$1 +shift +PROG=$1 +shift + +if test -z $OBJ; then + echo "This script is supposed to be run from 'make'." + exit 1 +fi + +echo "====> Benchmark results for $PROG" >$PROG-bench +size -t $OBJ | tail -n 1 >>$PROG-bench +wc -c $PROG >>$PROG-bench + +for i in $@; do + echo "== $i" >>$PROG-bench + cat $i >/dev/null + sh -c "time ./$PROG $i" >>$PROG-bench 2>&1 + sh -c "time ./$PROG $i" >>$PROG-bench 2>&1 +done -- cgit v1.2.3