Okay time to improve performances, gprof session:
before  real 0m2.483s (2.3.2 release yesterday)
current real 0m1.763s
when parsing (with tree build/freeing) db10000.xml from XSLTMark:
- xmlmemory.h HTMLparser.c HTMLtree.c entities.c parser.c
  xpath.c xpointer.c tree.c uri.c valid.c xinclude.c xmlIO.c:
  avoiding memcpy in production builds MEM_CLEANUP macro use
- parser.[ch] parserInternals.c: optimizations of the tightest
  internal loops inside the parser. Better checking of I/O
  flushing/loading conditions
- xmllint.c : added --timing
Daniel
diff --git a/ChangeLog b/ChangeLog
index a71d6b2..1c7dbb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sun Feb 25 18:03:42 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* xmlmemory.h HTMLparser.c HTMLtree.c entities.c parser.c
+	  xpath.c xpointer.c tree.c uri.c valid.c xinclude.c xmlIO.c:
+	  avoiding memcpy in production builds MEM_CLEANUP macro use
+	* parser.[ch] parserInternals.c: optimizations of the tightest
+	  internal loops inside the parser. Better checking of I/O
+	  flushing/loading conditions
+	* xmllint.c : added --timing
+
 Sun Feb 25 05:48:51 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* configure.in: bumped to 2.3.2
diff --git a/HTMLparser.c b/HTMLparser.c
index 4fb40df..9dffd58 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -1651,7 +1651,7 @@
         input->free((xmlChar *) input->base);
     if (input->buf != NULL) 
         xmlFreeParserInputBuffer(input->buf);
-    memset(input, -1, sizeof(htmlParserInput));
+    MEM_CLEANUP(input, sizeof(htmlParserInput));
     xmlFree(input);
 }
 
diff --git a/HTMLtree.c b/HTMLtree.c
index 8c6354a..bc328fc 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -663,7 +663,7 @@
     htmlDocContentDump(buf, cur);
     *mem = buf->content;
     *size = buf->use;
-    memset(buf, -1, sizeof(xmlBuffer));
+    MEM_CLEANUP(buf, sizeof(xmlBuffer));
     xmlFree(buf);
 }
 
diff --git a/aclocal.m4 b/aclocal.m4
index 869e5fc..e372675 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -620,31 +620,35 @@
 ])
 
 # AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl convenience library, adds --enable-ltdl-convenience to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments.  Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If DIR is not
+# provided, it is assumed to be `libltdl'.  LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   case "$enable_ltdl_convenience" in
   no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
   "") enable_ltdl_convenience=yes
       ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
   esac
-  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
-  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
 ])
 
 # AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl installable library, and adds --enable-ltdl-install to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments.  Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called.  If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!).  If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
 AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   AC_CHECK_LIB(ltdl, main,
@@ -657,8 +661,8 @@
   ])
   if test x"$enable_ltdl_install" = x"yes"; then
     ac_configure_args="$ac_configure_args --enable-ltdl-install"
-    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
-    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
   else
     ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
     LIBLTDL="-lltdl"
diff --git a/entities.c b/entities.c
index 0fc4e8e..8885c89 100644
--- a/entities.c
+++ b/entities.c
@@ -84,7 +84,7 @@
         xmlFree((char *) entity->content);
     if (entity->orig != NULL)
         xmlFree((char *) entity->orig);
-    memset(entity, -1, sizeof(xmlEntity));
+    MEM_CLEANUP(entity, sizeof(xmlEntity));
     xmlFree(entity);
 }
 
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index b98f2a3..0c82ce4 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -44,6 +44,7 @@
     const char *directory;            /* the directory/base of teh file */
     const xmlChar *base;              /* Base of the array to parse */
     const xmlChar *cur;               /* Current char being parsed */
+    const xmlChar *end;               /* end of the arry to parse */
     int length;                       /* length if known */
     int line;                         /* Current line */
     int col;                          /* Current column */
diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h
index 1e533d1..c909e4c 100644
--- a/include/libxml/xmlmemory.h
+++ b/include/libxml/xmlmemory.h
@@ -15,6 +15,7 @@
  * DEBUG_MEMORY_LOCATION should be activated only done when debugging 
  * libxml.
  */
+/* #define DEBUG_MEMORY_FREED */
 /* #define DEBUG_MEMORY_LOCATION */
 
 #ifdef DEBUG
@@ -27,6 +28,12 @@
 #define MEM_LIST /* keep a list of all the allocated memory blocks */
 #endif
 
+#ifdef DEBUG_MEMORY_FREED
+#define MEM_CLEANUP(p,l) memset((p), -1, (l));
+#else
+#define MEM_CLEANUP(p,l)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/parser.c b/parser.c
index 5541628..0077ea5 100644
--- a/parser.c
+++ b/parser.c
@@ -231,25 +231,24 @@
 #define SKIP(val) do {							\
     ctxt->nbChars += (val),ctxt->input->cur += (val);			\
     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
-    /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
     if ((*ctxt->input->cur == 0) &&					\
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
 	    xmlPopInput(ctxt);						\
   } while (0)
 
-#define SHRINK do {							\
+#define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) {\
     xmlParserInputShrink(ctxt->input);					\
     if ((*ctxt->input->cur == 0) &&					\
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
 	    xmlPopInput(ctxt);						\
-  } while (0)
+  }
 
-#define GROW do {							\
+#define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) {	\
     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);			\
     if ((*ctxt->input->cur == 0) &&					\
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
 	    xmlPopInput(ctxt);						\
-  } while (0)
+  }
 
 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
 
@@ -261,7 +260,6 @@
     } else ctxt->input->col++;						\
     ctxt->token = 0; ctxt->input->cur += l;				\
     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
-    /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
   } while (0)
 
 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
@@ -1610,11 +1608,35 @@
 xmlChar *
 xmlParseName(xmlParserCtxtPtr ctxt) {
     xmlChar buf[XML_MAX_NAMELEN + 5];
+    const xmlChar *in;
+    xmlChar *ret;
     int len = 0, l;
     int c;
     int count = 0;
 
     GROW;
+
+    /*
+     * Accelerator for simple ASCII names
+     */
+    in = ctxt->input->cur;
+    if (((*in >= 0x61) && (*in <= 0x7A)) ||
+	((*in >= 0x41) && (*in <= 0x5A)) ||
+	(*in == '_') || (*in == ':')) {
+	in++;
+	while (((*in >= 0x61) && (*in <= 0x7A)) ||
+	       ((*in >= 0x41) && (*in <= 0x5A)) ||
+	       ((*in >= 0x30) && (*in <= 0x39)) ||
+	       (*in == '_') || (*in == ':'))
+	    in++;
+	if ((*in == ' ') || (*in == '>') || (*in == '/')) {
+	    count = in - ctxt->input->cur;
+	    ret = xmlStrndup(ctxt->input->cur, count);
+	    ctxt->input->cur = in;
+	    return(ret);
+	}
+    }
+
     c = CUR_CHAR(l);
     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 	(!IS_LETTER(c) && (c != '_') &&
@@ -2370,6 +2392,7 @@
     return(buf);
 }
 
+void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
 /**
  * xmlParseCharData:
  * @ctxt:  an XML parser context
@@ -2388,6 +2411,61 @@
 
 void
 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
+    const xmlChar *in;
+    int nbchar = 0;
+
+    SHRINK;
+    GROW;
+    /*
+     * Accelerated common case where input don't need to be
+     * modified before passing it to the handler.
+     */
+    if ((ctxt->token == 0) && (!cdata)) {
+	in = ctxt->input->cur;
+	do {
+	    while (((*in >= 0x20) && (*in != '<') &&
+		    (*in != '&') && (*in <= 0x7F)) || (*in == 0x09))
+		in++;
+	    if (*in == 0xA) {
+		ctxt->input->line++;
+		continue; /* while */
+	    }
+	    nbchar = in - ctxt->input->cur;
+	    if (IS_BLANK(*ctxt->input->cur) &&
+		areBlanks(ctxt, ctxt->input->cur, nbchar)) {
+		if (ctxt->sax->ignorableWhitespace != NULL)
+		    ctxt->sax->ignorableWhitespace(ctxt->userData,
+					   ctxt->input->cur, nbchar);
+	    } else {
+		if (ctxt->sax->characters != NULL)
+		    ctxt->sax->characters(ctxt->userData,
+					  ctxt->input->cur, nbchar);
+	    }
+	    ctxt->input->cur = in;
+	    if (*in == 0xD) {
+		in++;
+		if (*in == 0xA) {
+		    ctxt->input->cur = in;
+		    in++;
+		    ctxt->input->line++;
+		    continue; /* while */
+		}
+		in--;
+	    }
+	    if ((*in == '<') || (*in == '&')) {
+		return;
+	    }
+	    SHRINK;
+	    GROW;
+	    in = ctxt->input->cur;
+	} while ((*in >= 0x20) && (*in <= 0x7F));
+	nbchar = 0;
+    }
+    xmlParseCharDataComplex(ctxt, cdata);
+}
+
+void
+xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
     int nbchar = 0;
     int cur, l;
@@ -8193,6 +8271,8 @@
 	xmlParserInputBufferPush(ctxt->input->buf, size, chunk);	      
 	ctxt->input->base = ctxt->input->buf->buffer->content + base;
 	ctxt->input->cur = ctxt->input->base + cur;
+	ctxt->input->end =
+	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
 #ifdef DEBUG_PUSH
 	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
 #endif
@@ -8327,6 +8407,8 @@
     inputStream->buf = buf;
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = 
+	&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
     if (enc != XML_CHAR_ENCODING_NONE) {
         xmlSwitchEncoding(ctxt, enc);
     }
@@ -9317,6 +9399,8 @@
     inputStream->buf = buf;
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = 
+	&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
 
     inputPush(ctxt, inputStream);
     if ((ctxt->directory == NULL) && (directory == NULL))
@@ -9455,6 +9539,7 @@
         input->filename = xmlMemStrdup(filename);
     input->base = buffer;
     input->cur = buffer;
+    input->end = &buffer[xmlStrlen(buffer)];
     inputPush(ctxt, input);
 }
 
@@ -9543,6 +9628,7 @@
     input->buf = buf;
     input->base = input->buf->buffer->content;
     input->cur = input->buf->buffer->content;
+    input->end = &input->buf->buffer->content[input->buf->buffer->use];
 
     inputPush(ctxt, input);
     return(ctxt);
diff --git a/parser.h b/parser.h
index b98f2a3..0c82ce4 100644
--- a/parser.h
+++ b/parser.h
@@ -44,6 +44,7 @@
     const char *directory;            /* the directory/base of teh file */
     const xmlChar *base;              /* Base of the array to parse */
     const xmlChar *cur;               /* Current char being parsed */
+    const xmlChar *end;               /* end of the arry to parse */
     int length;                       /* length if known */
     int line;                         /* Current line */
     int col;                          /* Current column */
diff --git a/parserInternals.c b/parserInternals.c
index 65ebf5f..e271e38 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -960,6 +960,7 @@
 	in->base = in->buf->buffer->content;
 	in->cur = &in->buf->buffer->content[index];
     }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
 
     CHECK_BUFFER(in);
 
@@ -1005,7 +1006,7 @@
         return(0);
 
     /*
-     * NOTE : in->base may be a "dandling" i.e. freed pointer in this
+     * NOTE : in->base may be a "dangling" i.e. freed pointer in this
      *        block, but we use it really as an integer to do some
      *        pointer arithmetic. Insure will raise it as a bug but in
      *        that specific case, that's not !
@@ -1018,6 +1019,7 @@
 	in->base = in->buf->buffer->content;
 	in->cur = &in->buf->buffer->content[index];
     }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
 
     CHECK_BUFFER(in);
 
@@ -1059,6 +1061,7 @@
 	    in->cur -= ret;
 	    in->consumed += ret;
 	}
+	in->end = &in->buf->buffer->content[in->buf->buffer->use];
     }
 
     CHECK_BUFFER(in);
@@ -1075,6 +1078,7 @@
 	in->base = in->buf->buffer->content;
 	in->cur = &in->buf->buffer->content[index];
     }
+    in->end = &in->buf->buffer->content[in->buf->buffer->use];
 
     CHECK_BUFFER(in);
 }
@@ -1769,6 +1773,8 @@
 		    }
 		    ctxt->input->base =
 		    ctxt->input->cur = ctxt->input->buf->buffer->content;
+		    ctxt->input->end =
+			&ctxt->input->base[ctxt->input->buf->buffer->use];
 
 		}
 		return(0);
@@ -1817,6 +1823,8 @@
 			ctxt->input->free((xmlChar *) ctxt->input->base);
 		    ctxt->input->base =
 		    ctxt->input->cur = ctxt->input->buf->buffer->content;
+		    ctxt->input->end =
+			&ctxt->input->base[ctxt->input->buf->buffer->use];
 		}
 	    }
 	} else {
@@ -1859,7 +1867,7 @@
         input->free((xmlChar *) input->base);
     if (input->buf != NULL) 
         xmlFreeParserInputBuffer(input->buf);
-    memset(input, -1, sizeof(xmlParserInput));
+    MEM_CLEANUP(input, sizeof(xmlParserInput));
     xmlFree(input);
 }
 
@@ -1918,6 +1926,7 @@
     inputStream->buf = input;
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
     if (enc != XML_CHAR_ENCODING_NONE) {
         xmlSwitchEncoding(ctxt, enc);
     }
@@ -1989,6 +1998,7 @@
     input->base = entity->content;
     input->cur = entity->content;
     input->length = entity->length;
+    input->end = &entity->content[input->length];
     return(input);
 }
 
@@ -2021,6 +2031,7 @@
     input->base = buffer;
     input->cur = buffer;
     input->length = xmlStrlen(buffer);
+    input->end = &buffer[input->length];
     return(input);
 }
 
@@ -2064,6 +2075,7 @@
 
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
+    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
     if ((ctxt->directory == NULL) && (directory != NULL))
         ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
     return(inputStream);
diff --git a/tree.c b/tree.c
index ae9c8c2..42acf7c 100644
--- a/tree.c
+++ b/tree.c
@@ -205,7 +205,7 @@
     }
     if (cur->href != NULL) xmlFree((char *) cur->href);
     if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
-    memset(cur, -1, sizeof(xmlNs));
+    MEM_CLEANUP(cur, sizeof(xmlNs));
     xmlFree(cur);
 }
 
@@ -423,7 +423,7 @@
     if (cur->pentities != NULL)
         xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
 
-    memset(cur, -1, sizeof(xmlDtd));
+    MEM_CLEANUP(cur, sizeof(xmlDtd));
     xmlFree(cur);
 }
 
@@ -485,7 +485,7 @@
     if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
     if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
     if (cur->URL != NULL) xmlFree((char *) cur->URL);
-    memset(cur, -1, sizeof(xmlDoc));
+    MEM_CLEANUP(cur, sizeof(xmlDoc));
     xmlFree(cur);
 }
 
@@ -1110,7 +1110,7 @@
         xmlRemoveID(cur->parent->doc, cur);
     if (cur->name != NULL) xmlFree((char *) cur->name);
     if (cur->children != NULL) xmlFreeNodeList(cur->children);
-    memset(cur, -1, sizeof(xmlAttr));
+    MEM_CLEANUP(cur, sizeof(xmlAttr));
     xmlFree(cur);
 }
 
@@ -2305,7 +2305,7 @@
 	(cur->name != xmlStringComment))
 	xmlFree((char *) cur->name);
     if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
-    memset(cur, -1, sizeof(xmlNode));
+    MEM_CLEANUP(cur, sizeof(xmlNode));
     xmlFree(cur);
 }
 
@@ -4511,13 +4511,13 @@
     }
     if (buf->content != NULL) {
 #ifndef XML_USE_BUFFER_CONTENT
-        memset(buf->content, -1, BASE_BUFFER_SIZE);
+        MEM_CLEANUP(buf->content, BASE_BUFFER_SIZE);
 #else
-        memset(buf->content, -1, buf->size);
+        MEM_CLEANUP(buf->content, buf->size);
 #endif
         xmlFree(buf->content);
     }
-    memset(buf, -1, sizeof(xmlBuffer));
+    MEM_CLEANUP(buf, sizeof(xmlBuffer));
     xmlFree(buf);
 }
 
@@ -4531,7 +4531,7 @@
 xmlBufferEmpty(xmlBufferPtr buf) {
     if (buf->content == NULL) return;
     buf->use = 0;
-    memset(buf->content, -1, buf->size);/* just for debug */
+    MEM_CLEANUP(buf->content, buf->size);
 }
 
 /**
diff --git a/uri.c b/uri.c
index 31875f7..51c1804 100644
--- a/uri.c
+++ b/uri.c
@@ -596,7 +596,7 @@
     if (uri->opaque != NULL) xmlFree(uri->opaque);
     if (uri->authority != NULL) xmlFree(uri->authority);
     if (uri->query != NULL) xmlFree(uri->query);
-    memset(uri, -1, sizeof(xmlURI));
+    MEM_CLEANUP(uri, sizeof(xmlURI));
     xmlFree(uri);
 }
 
diff --git a/valid.c b/valid.c
index 1b7e6f6..cbfa5e0 100644
--- a/valid.c
+++ b/valid.c
@@ -317,7 +317,7 @@
     if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
     if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
     if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-    memset(cur, -1, sizeof(xmlElementContent));
+    MEM_CLEANUP(cur, sizeof(xmlElementContent));
     xmlFree(cur);
 }
 
@@ -482,7 +482,7 @@
 	xmlFree((xmlChar *) elem->name);
     if (elem->prefix != NULL)
 	xmlFree((xmlChar *) elem->prefix);
-    memset(elem, -1, sizeof(xmlElement));
+    MEM_CLEANUP(elem, sizeof(xmlElement));
     xmlFree(elem);
 }
 
@@ -777,7 +777,7 @@
     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
 
     if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
-    memset(cur, -1, sizeof(xmlEnumeration));
+    MEM_CLEANUP(cur, sizeof(xmlEnumeration));
     xmlFree(cur);
 }
 
@@ -937,7 +937,7 @@
 	xmlFree((xmlChar *) attr->defaultValue);
     if (attr->prefix != NULL)
 	xmlFree((xmlChar *) attr->prefix);
-    memset(attr, -1, sizeof(xmlAttribute));
+    MEM_CLEANUP(attr, sizeof(xmlAttribute));
     xmlFree(attr);
 }
 
@@ -1285,7 +1285,7 @@
 	xmlFree((xmlChar *) nota->PublicID);
     if (nota->SystemID != NULL)
 	xmlFree((xmlChar *) nota->SystemID);
-    memset(nota, -1, sizeof(xmlNotation));
+    MEM_CLEANUP(nota, sizeof(xmlNotation));
     xmlFree(nota);
 }
 
@@ -1489,7 +1489,7 @@
     if (id == NULL) return;
     if (id->value != NULL)
 	xmlFree((xmlChar *) id->value);
-    memset(id, -1, sizeof(xmlID));
+    MEM_CLEANUP(id, sizeof(xmlID));
     xmlFree(id);
 }
 
@@ -1717,7 +1717,7 @@
 	if (ref == NULL) return;
 	if (ref->value != NULL)
 		xmlFree((xmlChar *)ref->value);
-	memset(ref, -1, sizeof(xmlRef));
+	MEM_CLEANUP(ref, sizeof(xmlRef));
 	xmlFree(ref);
 }
 
diff --git a/xinclude.c b/xinclude.c
index c377f64..343eef7 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -281,7 +281,7 @@
 	xmlFree(ctxt->txtTab);
     if (ctxt->txturlTab != NULL)
 	xmlFree(ctxt->txturlTab);
-    memset(ctxt, 0xeb, sizeof(xmlXIncludeCtxt));
+    MEM_CLEANUP(ctxt, sizeof(xmlXIncludeCtxt));
     xmlFree(ctxt);
 }
 
diff --git a/xmlIO.c b/xmlIO.c
index 290ceab..f623af9 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -908,7 +908,7 @@
 	in->buffer = NULL;
     }
 
-    memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer));
+    MEM_CLEANUP(in, (size_t) sizeof(xmlParserInputBuffer));
     xmlFree(in);
 }
 
@@ -945,7 +945,7 @@
 	out->buffer = NULL;
     }
 
-    memset(out, 0xbe, (size_t) sizeof(xmlOutputBuffer));
+    MEM_CLEANUP(out, (size_t) sizeof(xmlOutputBuffer));
     xmlFree(out);
     return(written);
 }
diff --git a/xmllint.c b/xmllint.c
index df4b4c1..332146a 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -16,6 +16,8 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <sys/time.h>
+
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -88,6 +90,8 @@
 static int xinclude = 0;
 #endif
 static int progresult = 0;
+static int timing = 0;
+static struct timeval begin, end;
 
 
 #ifdef VMS
@@ -386,6 +390,10 @@
 void parseAndPrintFile(char *filename) {
     xmlDocPtr doc = NULL, tmp;
 
+    if ((timing) && (!repeat))
+	gettimeofday(&begin, NULL);
+    
+
 #ifdef LIBXML_HTML_ENABLED
     if (html) {
 	doc = htmlParseFile(filename, NULL);
@@ -527,9 +535,30 @@
 	return;
     }
 
+    if ((timing) && (!repeat)) {
+	long msec;
+	gettimeofday(&end, NULL);
+	msec = end.tv_sec - begin.tv_sec;
+	msec *= 1000;
+	msec += (end.tv_usec - begin.tv_usec) / 1000;
+	fprintf(stderr, "Parsing took %ld ms\n", msec);
+    }
+
 #ifdef LIBXML_XINCLUDE_ENABLED
-    if (xinclude)
+    if (xinclude) {
+	if ((timing) && (!repeat)) {
+	    gettimeofday(&begin, NULL);
+	}
 	xmlXIncludeProcess(doc);
+	if ((timing) && (!repeat)) {
+	    long msec;
+	    gettimeofday(&end, NULL);
+	    msec = end.tv_sec - begin.tv_sec;
+	    msec *= 1000;
+	    msec += (end.tv_usec - begin.tv_usec) / 1000;
+	    fprintf(stderr, "Xinclude processing took %ld ms\n", msec);
+	}
+    }
 #endif
 
 #ifdef LIBXML_DEBUG_ENABLED
@@ -579,6 +608,9 @@
 #ifdef LIBXML_DEBUG_ENABLED
 	if (!debug) {
 #endif
+	    if ((timing) && (!repeat)) {
+		gettimeofday(&begin, NULL);
+	    }
 	    if (memory) {
 		xmlChar *result;
 		int len;
@@ -600,6 +632,14 @@
 	        xmlSaveFileEnc("-", doc, encoding);
 	    else
 		xmlDocDump(stdout, doc);
+	    if ((timing) && (!repeat)) {
+		long msec;
+		gettimeofday(&end, NULL);
+		msec = end.tv_sec - begin.tv_sec;
+		msec *= 1000;
+		msec += (end.tv_usec - begin.tv_usec) / 1000;
+		fprintf(stderr, "Saving took %ld ms\n", msec);
+	    }
 #ifdef LIBXML_DEBUG_ENABLED
 	} else {
 	    xmlDebugDumpDocument(stdout, doc);
@@ -613,13 +653,27 @@
     if (dtdvalid != NULL) {
 	xmlDtdPtr dtd;
 
+	if ((timing) && (!repeat)) {
+	    gettimeofday(&begin, NULL);
+	}
 	dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); 
+	if ((timing) && (!repeat)) {
+	    long msec;
+	    gettimeofday(&end, NULL);
+	    msec = end.tv_sec - begin.tv_sec;
+	    msec *= 1000;
+	    msec += (end.tv_usec - begin.tv_usec) / 1000;
+	    fprintf(stderr, "Parsing DTD took %ld ms\n", msec);
+	}
 	if (dtd == NULL) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "Could not parse DTD %s\n", dtdvalid);
 	    progresult = 2;
 	} else {
 	    xmlValidCtxt cvp;
+	    if ((timing) && (!repeat)) {
+		gettimeofday(&begin, NULL);
+	    }
 	    cvp.userData = (void *) stderr;                                                 cvp.error    = (xmlValidityErrorFunc) fprintf;                                  cvp.warning  = (xmlValidityWarningFunc) fprintf;
 	    if (!xmlValidateDtd(&cvp, doc, dtd)) {
 		xmlGenericError(xmlGenericErrorContext,
@@ -627,16 +681,35 @@
 			filename, dtdvalid);
 		progresult = 3;
 	    }
+	    if ((timing) && (!repeat)) {
+		long msec;
+		gettimeofday(&end, NULL);
+		msec = end.tv_sec - begin.tv_sec;
+		msec *= 1000;
+		msec += (end.tv_usec - begin.tv_usec) / 1000;
+		fprintf(stderr, "Validating against DTD took %ld ms\n", msec);
+	    }
 	    xmlFreeDtd(dtd);
 	}
     } else if (postvalid) {
 	xmlValidCtxt cvp;
+	if ((timing) && (!repeat)) {
+	    gettimeofday(&begin, NULL);
+	}
 	cvp.userData = (void *) stderr;                                                 cvp.error    = (xmlValidityErrorFunc) fprintf;                                  cvp.warning  = (xmlValidityWarningFunc) fprintf;
 	if (!xmlValidateDocument(&cvp, doc)) {
 	    xmlGenericError(xmlGenericErrorContext,
 		    "Document %s does not validate\n", filename);
 	    progresult = 3;
 	}
+	if ((timing) && (!repeat)) {
+	    long msec;
+	    gettimeofday(&end, NULL);
+	    msec = end.tv_sec - begin.tv_sec;
+	    msec *= 1000;
+	    msec += (end.tv_usec - begin.tv_usec) / 1000;
+	    fprintf(stderr, "Validating took %ld ms\n", msec);
+	}
     }
 
 #ifdef LIBXML_DEBUG_ENABLED
@@ -647,7 +720,18 @@
     /*
      * free it.
      */
+    if ((timing) && (!repeat)) {
+	gettimeofday(&begin, NULL);
+    }
     xmlFreeDoc(doc);
+    if ((timing) && (!repeat)) {
+	long msec;
+	gettimeofday(&end, NULL);
+	msec = end.tv_sec - begin.tv_sec;
+	msec *= 1000;
+	msec += (end.tv_usec - begin.tv_usec) / 1000;
+	fprintf(stderr, "Freeing took %ld ms\n", msec);
+    }
 }
 
 int
@@ -703,6 +787,9 @@
 	else if ((!strcmp(argv[i], "-insert")) ||
 	         (!strcmp(argv[i], "--insert")))
 	    insert++;
+	else if ((!strcmp(argv[i], "-timing")) ||
+	         (!strcmp(argv[i], "--timing")))
+	    timing++;
 	else if ((!strcmp(argv[i], "-repeat")) ||
 	         (!strcmp(argv[i], "--repeat")))
 	    repeat++;
@@ -784,6 +871,8 @@
 	    i++;
 	    continue;
         }
+	if ((timing) && (repeat))
+	    gettimeofday(&begin, NULL);
 	/* Remember file names.  "-" means stding.  <sven@zen.org> */
 	if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
 	    if (repeat) {
@@ -793,12 +882,20 @@
 		parseAndPrintFile(argv[i]);
 	    files ++;
 	}
+	if ((timing) && (repeat)) {
+	    long msec;
+	    gettimeofday(&end, NULL);
+	    msec = end.tv_sec - begin.tv_sec;
+	    msec *= 1000;
+	    msec += (end.tv_usec - begin.tv_usec) / 1000;
+	    fprintf(stderr, "100 iteration took %ld ms\n", msec);
+	}
     }
     if ((htmlout) && (!nowrap)) {
 	xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
     }
     if (files == 0) {
-	printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
+	printf("Usage : %s [options] XMLfiles ...\n",
 	       argv[0]);
 	printf("\tParse the XML files and output the result of the parsing\n");
 #ifdef LIBXML_DEBUG_ENABLED
@@ -815,6 +912,7 @@
 	printf("\t--valid : validate the document in addition to std well-formed check\n");
 	printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
 	printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
+	printf("\t--timing : print some timings\n");
 	printf("\t--repeat : repeat 100 times, for timing or profiling\n");
 	printf("\t--insert : ad-hoc test for valid insertions\n");
 	printf("\t--compress : turn on gzip compression of output\n");
diff --git a/xmlmemory.h b/xmlmemory.h
index 1e533d1..c909e4c 100644
--- a/xmlmemory.h
+++ b/xmlmemory.h
@@ -15,6 +15,7 @@
  * DEBUG_MEMORY_LOCATION should be activated only done when debugging 
  * libxml.
  */
+/* #define DEBUG_MEMORY_FREED */
 /* #define DEBUG_MEMORY_LOCATION */
 
 #ifdef DEBUG
@@ -27,6 +28,12 @@
 #define MEM_LIST /* keep a list of all the allocated memory blocks */
 #endif
 
+#ifdef DEBUG_MEMORY_FREED
+#define MEM_CLEANUP(p,l) memset((p), -1, (l));
+#else
+#define MEM_CLEANUP(p,l)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/xpath.c b/xpath.c
index 63903f0..ff7a89b 100644
--- a/xpath.c
+++ b/xpath.c
@@ -906,14 +906,10 @@
 xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
     if (obj == NULL) return;
     if (obj->nodeTab != NULL) {
-#ifdef DEBUG
-	memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
-#endif
+	MEM_CLEANUP(obj->nodeTab, (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
 	xmlFree(obj->nodeTab);
     }
-#ifdef DEBUG
-    memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
-#endif
+    MEM_CLEANUP(obj, (size_t) sizeof(xmlNodeSet));
     xmlFree(obj);
 }
 
@@ -934,14 +930,10 @@
 	    xmlFreeNodeList(obj->nodeTab[i]);
 
     if (obj->nodeTab != NULL) {
-#ifdef DEBUG
-	memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
-#endif
+	MEM_CLEANUP(obj->nodeTab, (size_t) sizeof(xmlNodePtr) * obj->nodeMax);
 	xmlFree(obj->nodeTab);
     }
-#ifdef DEBUG
-    memset(obj, 0xB , (size_t) sizeof(xmlNodeSet));
-#endif
+    MEM_CLEANUP(obj, (size_t) sizeof(xmlNodeSet));
     xmlFree(obj);
 }
 
@@ -1098,9 +1090,7 @@
 void
 xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
     if (obj == NULL) return;
-#ifdef DEBUG
-    memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
-#endif
+    MEM_CLEANUP(obj, (size_t) sizeof(xmlXPathObject));
     xmlFree(obj);
 }
 
@@ -1611,9 +1601,7 @@
 	    xmlXPathFreeValueTree(obj->nodesetval);
     }
 
-#ifdef DEBUG
-    memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
-#endif
+    MEM_CLEANUP(obj, (size_t) sizeof(xmlXPathObject));
     xmlFree(obj);
 }
 
@@ -1679,9 +1667,7 @@
     xmlXPathRegisteredNsCleanup(ctxt);
     xmlXPathRegisteredFuncsCleanup(ctxt);
     xmlXPathRegisteredVariablesCleanup(ctxt);
-#ifdef DEBUG
-    memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
-#endif
+    MEM_CLEANUP(ctxt, (size_t) sizeof(xmlXPathContext));
     xmlFree(ctxt);
 }
 
@@ -1758,14 +1744,10 @@
 void
 xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
     if (ctxt->valueTab != NULL) {
-#ifdef DEBUG
-        memset(ctxt->valueTab, 0xB , 10 * (size_t) sizeof(xmlXPathObjectPtr));
-#endif
+        MEM_CLEANUP(ctxt->valueTab, 10 * (size_t) sizeof(xmlXPathObjectPtr));
         xmlFree(ctxt->valueTab);
     }
-#ifdef DEBUG
-    memset(ctxt, 0xB , (size_t) sizeof(xmlXPathParserContext));
-#endif
+    MEM_CLEANUP(ctxt, (size_t) sizeof(xmlXPathParserContext));
     xmlFree(ctxt);
 }
 
diff --git a/xpointer.c b/xpointer.c
index 7d2da1b..9380d15 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -715,15 +715,11 @@
 	for (i = 0;i < obj->locNr; i++) {
             xmlXPathFreeObject(obj->locTab[i]);
 	}
-#ifdef DEBUG
-	memset(obj->locTab, 0xB ,
+	MEM_CLEANUP(obj->locTab,
 	       (size_t) sizeof(xmlXPathObjectPtr) * obj->locMax);
-#endif
 	xmlFree(obj->locTab);
     }
-#ifdef DEBUG
-    memset(obj, 0xB , (size_t) sizeof(xmlLocationSet));
-#endif
+    MEM_CLEANUP(obj, (size_t) sizeof(xmlLocationSet));
     xmlFree(obj);
 }