mirror of
https://github.com/GNOME/libxml2.git
synced 2025-02-11 18:09:31 +08:00
optimization when freeing hash tables. some tuning of buffer allocations
* dict.c hash.c: optimization when freeing hash tables. * parser.c xmlIO.c include/libxml/tree.h: some tuning of buffer allocations * parser.c parserInternals.c include/libxml/parser.h: keep a single allocated block for all the attributes callbacks, avoid useless malloc()/free() * tree.c: do not realloc() when growing a buffer if the buffer ain't full, malloc/memcpy/free avoid copying memory. Daniel
This commit is contained in:
parent
66f68e716b
commit
6155d8aafa
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
Tue Aug 19 16:54:18 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* dict.c hash.c: optimization when freeing hash tables.
|
||||
* parser.c xmlIO.c include/libxml/tree.h: some tuning of buffer
|
||||
allocations
|
||||
* parser.c parserInternals.c include/libxml/parser.h: keep a
|
||||
single allocated block for all the attributes callbacks,
|
||||
avoid useless malloc()/free()
|
||||
* tree.c: do not realloc() when growing a buffer if the buffer
|
||||
ain't full, malloc/memcpy/free avoid copying memory.
|
||||
|
||||
Mon Aug 18 18:37:01 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* xmllint.c doc/xmllint.xml doc/xmllint.1: added option
|
||||
|
3
dict.c
3
dict.c
@ -232,7 +232,7 @@ xmlDictFree(xmlDictPtr dict) {
|
||||
if (dict == NULL)
|
||||
return;
|
||||
if (dict->dict) {
|
||||
for(i = 0; i < dict->size; i++) {
|
||||
for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) {
|
||||
iter = &(dict->dict[i]);
|
||||
if (iter->valid == 0)
|
||||
continue;
|
||||
@ -243,6 +243,7 @@ xmlDictFree(xmlDictPtr dict) {
|
||||
xmlFree(iter->name);
|
||||
if (!inside_dict)
|
||||
xmlFree(iter);
|
||||
dict->nbElems--;
|
||||
inside_dict = 0;
|
||||
iter = next;
|
||||
}
|
||||
|
5
hash.c
5
hash.c
@ -218,11 +218,13 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
|
||||
xmlHashEntryPtr iter;
|
||||
xmlHashEntryPtr next;
|
||||
int inside_table = 0;
|
||||
int nbElems;
|
||||
|
||||
if (table == NULL)
|
||||
return;
|
||||
if (table->table) {
|
||||
for(i = 0; i < table->size; i++) {
|
||||
nbElems = table->nbElems;
|
||||
for(i = 0; (i < table->size) && (nbElems > 0); i++) {
|
||||
iter = &(table->table[i]);
|
||||
if (iter->valid == 0)
|
||||
continue;
|
||||
@ -240,6 +242,7 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
|
||||
iter->payload = NULL;
|
||||
if (!inside_table)
|
||||
xmlFree(iter);
|
||||
nbElems--;
|
||||
inside_table = 0;
|
||||
iter = next;
|
||||
}
|
||||
|
@ -236,6 +236,8 @@ struct _xmlParserCtxt {
|
||||
int recovery; /* run in recovery mode */
|
||||
int progressive; /* is this a progressive parsing */
|
||||
xmlDictPtr dict; /* dictionnary for the parser */
|
||||
const xmlChar * *atts; /* array for the attributes callbacks */
|
||||
int maxatts; /* the size of the array */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ typedef xmlEntity *xmlEntityPtr;
|
||||
*
|
||||
* default buffer size 4000.
|
||||
*/
|
||||
#define BASE_BUFFER_SIZE 4000
|
||||
#define BASE_BUFFER_SIZE 4096
|
||||
|
||||
/**
|
||||
* XML_XML_NAMESPACE:
|
||||
|
32
parser.c
32
parser.c
@ -369,8 +369,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
|
||||
} while (0)
|
||||
|
||||
#define SHRINK if ((ctxt->progressive == 0) && \
|
||||
(ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) && \
|
||||
(ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
|
||||
(ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
|
||||
(ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
|
||||
xmlSHRINK (ctxt);
|
||||
|
||||
static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
|
||||
@ -2363,6 +2363,7 @@ xmlParseAttValue(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar limit = 0;
|
||||
const xmlChar *in = NULL;
|
||||
xmlChar *ret = NULL;
|
||||
|
||||
SHRINK;
|
||||
GROW;
|
||||
in = (xmlChar *) CUR_PTR;
|
||||
@ -2412,8 +2413,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *current = NULL;
|
||||
xmlEntityPtr ent;
|
||||
|
||||
|
||||
SHRINK;
|
||||
if (NXT(0) == '"') {
|
||||
ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
|
||||
limit = '"';
|
||||
@ -6612,9 +6611,9 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *name;
|
||||
const xmlChar *attname;
|
||||
xmlChar *attvalue;
|
||||
const xmlChar **atts = NULL;
|
||||
const xmlChar **atts = ctxt->atts;
|
||||
int nbatts = 0;
|
||||
int maxatts = 0;
|
||||
int maxatts = ctxt->maxatts;
|
||||
int i;
|
||||
|
||||
if (RAW != '<') return(NULL);
|
||||
@ -6670,8 +6669,9 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
|
||||
* Add the pair to atts
|
||||
*/
|
||||
if (atts == NULL) {
|
||||
maxatts = 10;
|
||||
atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
|
||||
maxatts = 22; /* allow for 10 attrs by default */
|
||||
atts = (const xmlChar **)
|
||||
xmlMalloc(maxatts * sizeof(xmlChar *));
|
||||
if (atts == NULL) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"malloc of %ld byte failed\n",
|
||||
@ -6683,12 +6683,14 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
|
||||
ctxt->disableSAX = 1;
|
||||
goto failed;
|
||||
}
|
||||
ctxt->atts = atts;
|
||||
ctxt->maxatts = maxatts;
|
||||
} else if (nbatts + 4 > maxatts) {
|
||||
const xmlChar **n;
|
||||
|
||||
maxatts *= 2;
|
||||
n = (const xmlChar **) xmlRealloc((void *) atts,
|
||||
maxatts * sizeof(xmlChar *));
|
||||
maxatts * sizeof(const xmlChar *));
|
||||
if (n == NULL) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"realloc of %ld byte failed\n",
|
||||
@ -6701,6 +6703,8 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
|
||||
goto failed;
|
||||
}
|
||||
atts = n;
|
||||
ctxt->atts = atts;
|
||||
ctxt->maxatts = maxatts;
|
||||
}
|
||||
atts[nbatts++] = attname;
|
||||
atts[nbatts++] = attvalue;
|
||||
@ -6735,6 +6739,7 @@ failed:
|
||||
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
|
||||
break;
|
||||
}
|
||||
SHRINK;
|
||||
GROW;
|
||||
}
|
||||
|
||||
@ -6742,15 +6747,18 @@ failed:
|
||||
* SAX: Start of Element !
|
||||
*/
|
||||
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
|
||||
(!ctxt->disableSAX))
|
||||
ctxt->sax->startElement(ctxt->userData, name, atts);
|
||||
(!ctxt->disableSAX)) {
|
||||
if (nbatts > 0)
|
||||
ctxt->sax->startElement(ctxt->userData, name, atts);
|
||||
else
|
||||
ctxt->sax->startElement(ctxt->userData, name, NULL);
|
||||
}
|
||||
|
||||
if (atts != NULL) {
|
||||
/* Free only the content strings */
|
||||
for (i = 1;i < nbatts;i+=2)
|
||||
if (atts[i] != NULL)
|
||||
xmlFree((xmlChar *) atts[i]);
|
||||
xmlFree((void *) atts);
|
||||
}
|
||||
return(name);
|
||||
}
|
||||
|
@ -2218,6 +2218,8 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
||||
else
|
||||
memcpy(ctxt->sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
|
||||
|
||||
ctxt->maxatts = 0;
|
||||
ctxt->atts = NULL;
|
||||
/* Allocate the Input stack */
|
||||
ctxt->inputTab = (xmlParserInputPtr *)
|
||||
xmlMalloc(5 * sizeof(xmlParserInputPtr));
|
||||
@ -2369,6 +2371,7 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
|
||||
xmlFree(ctxt->sax);
|
||||
if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
|
||||
if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
|
||||
if (ctxt->atts != NULL) xmlFree(ctxt->atts);
|
||||
if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
|
||||
#ifdef LIBXML_CATALOG_ENABLED
|
||||
if (ctxt->catalogs != NULL)
|
||||
|
14
tree.c
14
tree.c
@ -6413,9 +6413,21 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
||||
|
||||
if (buf->content == NULL)
|
||||
rebuf = (xmlChar *) xmlMallocAtomic(newSize * sizeof(xmlChar));
|
||||
else
|
||||
else if (buf->size - buf->use < 100) {
|
||||
rebuf = (xmlChar *) xmlRealloc(buf->content,
|
||||
newSize * sizeof(xmlChar));
|
||||
} else {
|
||||
/*
|
||||
* if we are reallocating a buffer far from being full, it's
|
||||
* better to make a new allocation and copy only the used range
|
||||
* and free the old one.
|
||||
*/
|
||||
rebuf = (xmlChar *) xmlMallocAtomic(newSize * sizeof(xmlChar));
|
||||
if (rebuf != NULL) {
|
||||
memcpy(rebuf, buf->content, buf->use);
|
||||
xmlFree(buf->content);
|
||||
}
|
||||
}
|
||||
if (rebuf == NULL) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlBufferResize : out of memory!\n");
|
||||
|
9
xmlIO.c
9
xmlIO.c
@ -1574,7 +1574,7 @@ xmlAllocParserInputBuffer(xmlCharEncoding enc) {
|
||||
return(NULL);
|
||||
}
|
||||
memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
|
||||
ret->buffer = xmlBufferCreate();
|
||||
ret->buffer = xmlBufferCreateSize(2 * xmlDefaultBufferSize);
|
||||
if (ret->buffer == NULL) {
|
||||
xmlFree(ret);
|
||||
return(NULL);
|
||||
@ -1582,7 +1582,7 @@ xmlAllocParserInputBuffer(xmlCharEncoding enc) {
|
||||
ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
|
||||
ret->encoder = xmlGetCharEncodingHandler(enc);
|
||||
if (ret->encoder != NULL)
|
||||
ret->raw = xmlBufferCreate();
|
||||
ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize);
|
||||
else
|
||||
ret->raw = NULL;
|
||||
ret->readcallback = NULL;
|
||||
@ -2173,16 +2173,15 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
|
||||
int buffree;
|
||||
unsigned int needSize;
|
||||
|
||||
if ((len <= MINLEN) && (len != 4))
|
||||
if ((len <= MINLEN) && (len != 4))
|
||||
len = MINLEN;
|
||||
|
||||
buffree = in->buffer->size - in->buffer->use;
|
||||
if (buffree <= 0) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlParserInputBufferGrow : buffer full !\n");
|
||||
return(0);
|
||||
}
|
||||
if (len > buffree)
|
||||
len = buffree;
|
||||
|
||||
needSize = in->buffer->use + len + 1;
|
||||
if (needSize > in->buffer->size){
|
||||
|
Loading…
Reference in New Issue
Block a user