Re: b-a-s .server files & cold start ...
- From: "Tommi Komulainen" <tommi komulainen iki fi>
- To: michael meeks novell com
- Cc: rodrigo novell com, performance-list <performance-list gnome org>
- Subject: Re: b-a-s .server files & cold start ...
- Date: Thu, 16 Mar 2006 20:02:07 +0200
On 3/16/06, michael meeks <michael meeks novell com> wrote:
> I think it's safe to say that a full-blown XML implementation is not
> really necessary for reading a few simple .server files; we should
> prolly switch to GMarkup.
While not necessary, I wouldn't be so certain about getting any more
performance out of GMarkup. I once wrote a silly benchmark for three
XML parsers (expat, libxml2, GMarkup) using empty callbacks, so any
time spent is because of the parser (application logic would be
virtually identical in all cases.)
See attachment. Usage: ./testxml [--mmap] anyfile.xml
--
Tommi Komulainen tommi komulainen iki fi
/*
gcc -Wall -O2 -g `pkg-config --cflags --libs glib-2.0 libxml-2.0` -lexpat -o testxml testxml.c
*/
#include <glib.h>
#include <libxml/parser.h>
#include <expat.h>
#define DEFAULT_REPEAT 10
/************************************************************************
* GMarkup
*/
static void start_element_gmarkup (GMarkupParseContext *ctxt, const gchar *name, const gchar **attnames, const gchar **attvals, gpointer user_data, GError **error) { }
static void end_element_gmarkup (GMarkupParseContext *ctxt, const char *name, gpointer user_data, GError **error) { }
static void text_gmarkup (GMarkupParseContext *ctxt, const gchar *text, gsize text_len, gpointer user_data, GError **error) { }
static inline void
time_gmarkup (const char *text, gsize text_len)
{
static const GMarkupParser parser = {
.start_element = start_element_gmarkup,
.end_element = end_element_gmarkup,
.text = text_gmarkup,
};
GMarkupParseContext *ctxt;
ctxt = g_markup_parse_context_new (&parser, 0, NULL, NULL);
g_assert (ctxt != NULL);
g_assert (g_markup_parse_context_parse (ctxt, text, text_len, NULL));
g_assert (g_markup_parse_context_end_parse (ctxt, NULL));
g_markup_parse_context_free (ctxt);
}
/************************************************************************
* libxml2
*/
static void start_element_libxml (void *ctxt, const xmlChar *name, const xmlChar **atts) { }
static void end_element_libxml (void *ctxt, const xmlChar *name) { }
static void characters_libxml (void *ctxt, const xmlChar *ch, int len) { }
static inline void
time_libxml2 (const char *text, gsize text_len)
{
static xmlSAXHandler parser = {
.startElement = start_element_libxml,
.endElement = end_element_libxml,
.characters = characters_libxml
};
xmlParserCtxtPtr ctxt;
ctxt = xmlCreatePushParserCtxt(&parser, NULL, text, 4, "");
g_assert (ctxt != NULL);
xmlParseChunk(ctxt, text+4, text_len-4, 1);
xmlFreeParserCtxt(ctxt);
}
/************************************************************************
* expat
*/
static void start_element_expat (void *userData, const XML_Char *name, const XML_Char **atts) { }
static void end_element_expat (void *userData, const XML_Char *name) { }
static void character_expat (void *userData, const XML_Char *s, int len) { }
static inline void
time_expat (const char *text, gsize text_len)
{
XML_Parser parser;
parser = XML_ParserCreate("UTF-8");
XML_SetElementHandler(parser, start_element_expat, end_element_expat);
XML_SetCharacterDataHandler(parser, character_expat);
if (XML_Parse(parser, text, text_len, 1) != XML_STATUS_OK) {
g_printerr(" %d:%d: %s\n",
XML_GetCurrentLineNumber(parser),
XML_GetCurrentColumnNumber(parser),
XML_ErrorString(XML_GetErrorCode(parser)));
exit(1);
}
XML_ParserFree(parser);
}
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int
main (int argc, char **argv)
{
const char *filename;
char *text;
gsize text_len;
GTimer *timer;
gboolean use_mmap = FALSE;
int i;
int repeat;
gdouble elapsed;
timer = g_timer_new ();
++argv; --argc;
if (argc > 1 && strcmp(*argv, "--mmap") == 0)
{
use_mmap = 1;
++argv; --argc;
}
filename = *argv;
++argv; --argc;
if (argc > 0)
{
repeat = atoi(*argv);
g_assert (repeat > 0);
++argv; --argc;
}
else
repeat = DEFAULT_REPEAT;
if (use_mmap)
{
int fd;
struct stat st;
void *mem;
printf("using mmap\n");
g_assert((fd = open(filename, O_RDONLY)) != -1);
g_assert(fstat(fd, &st) == 0);
g_assert((mem = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED);
close(fd);
text_len = st.st_size;
text = mem;
}
else
{
printf("using memory buffer\n");
g_assert (g_file_get_contents (filename, &text, &text_len, NULL));
}
printf("parser cnt total average\n");
printf("GMarkup "); fflush(stdout);
g_timer_start (timer);
for (i = 0; i < repeat; i++)
time_gmarkup(text, text_len);
elapsed = g_timer_elapsed(timer, NULL);
printf("%3d %.6f %.6f\n", repeat, elapsed, elapsed/repeat);
printf("libxml2 "); fflush(stdout);
g_timer_start (timer);
for (i = 0; i < repeat; i++)
time_libxml2(text, text_len);
elapsed = g_timer_elapsed(timer, NULL);
printf("%3d %.6f %.6f\n", repeat, elapsed, elapsed/repeat);
printf(" expat "); fflush(stdout);
g_timer_start (timer);
for (i = 0; i < repeat; i++)
time_expat(text, text_len);
elapsed = g_timer_elapsed(timer, NULL);
printf("%3d %.6f %.6f\n", repeat, elapsed, elapsed/repeat);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]