From 15cc3bf67036c204ace466be4232bfed8cf76d2e Mon Sep 17 00:00:00 2001 From: def Date: Thu, 19 Feb 2015 21:45:08 +0100 Subject: Improve performance of parsexml - Prevent string copies when not necessary - Don't allocate a new XMLParser.c all the time --- lib/pure/parsexml.nim | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index b957c0cf7..6e6f6ab5d 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -128,6 +128,7 @@ proc open*(my: var XmlParser, input: Stream, filename: string, my.kind = xmlError my.a = "" my.b = "" + my.c = "" my.options = options proc close*(my: var XmlParser) {.inline.} = @@ -138,40 +139,40 @@ proc kind*(my: XmlParser): XmlEventKind {.inline.} = ## returns the current event type for the XML parser return my.kind -proc charData*(my: XmlParser): string {.inline.} = +proc charData*(my: var XmlParser): var string {.inline.} = ## returns the character data for the events: ``xmlCharData``, ## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial`` assert(my.kind in {xmlCharData, xmlWhitespace, xmlComment, xmlCData, xmlSpecial}) return my.a -proc elementName*(my: XmlParser): string {.inline.} = +proc elementName*(my: var XmlParser): var string {.inline.} = ## returns the element name for the events: ``xmlElementStart``, ## ``xmlElementEnd``, ``xmlElementOpen`` assert(my.kind in {xmlElementStart, xmlElementEnd, xmlElementOpen}) return my.a -proc entityName*(my: XmlParser): string {.inline.} = +proc entityName*(my: var XmlParser): var string {.inline.} = ## returns the entity name for the event: ``xmlEntity`` assert(my.kind == xmlEntity) return my.a -proc attrKey*(my: XmlParser): string {.inline.} = +proc attrKey*(my: var XmlParser): var string {.inline.} = ## returns the attribute key for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.a -proc attrValue*(my: XmlParser): string {.inline.} = +proc attrValue*(my: var XmlParser): var string {.inline.} = ## returns the attribute value for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.b -proc piName*(my: XmlParser): string {.inline.} = +proc piName*(my: var XmlParser): var string {.inline.} = ## returns the processing instruction name for the event ``xmlPI`` assert(my.kind == xmlPI) return my.a -proc piRest*(my: XmlParser): string {.inline.} = +proc piRest*(my: var XmlParser): var string {.inline.} = ## returns the rest of the processing instruction for the event ``xmlPI`` assert(my.kind == xmlPI) return my.b @@ -446,13 +447,15 @@ proc parseTag(my: var XmlParser) = # an attribute follows: my.kind = xmlElementOpen my.state = stateAttr - my.c = my.a # save for later + # save for later: + my.c.setLen(my.a.len) + copyMem(addr my.c[0], addr my.a[0], my.a.len+1) else: my.kind = xmlElementStart if my.buf[my.bufpos] == '/' and my.buf[my.bufpos+1] == '>': inc(my.bufpos, 2) my.state = stateEmptyElementTag - my.c = nil + my.c.setLen(0) elif my.buf[my.bufpos] == '>': inc(my.bufpos) else: @@ -621,8 +624,9 @@ proc next*(my: var XmlParser) = of stateEmptyElementTag: my.state = stateNormal my.kind = xmlElementEnd - if not isNil(my.c): - my.a = my.c + if my.c.len > 0: + my.a.setLen(my.c.len) + copyMem(addr my.a[0], addr my.c[0], my.c.len+1) of stateError: my.kind = xmlError my.state = stateNormal -- cgit 1.4.1-2-gfad0 From ba63a8f8b8b3706660c7b257327269473e3a584c Mon Sep 17 00:00:00 2001 From: def Date: Thu, 19 Feb 2015 22:29:41 +0100 Subject: Use templates in parsexml instead for performance --- lib/pure/parsexml.nim | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 6e6f6ab5d..a9fdf87b4 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -139,43 +139,43 @@ proc kind*(my: XmlParser): XmlEventKind {.inline.} = ## returns the current event type for the XML parser return my.kind -proc charData*(my: var XmlParser): var string {.inline.} = +template charData*(my: XmlParser): string = ## returns the character data for the events: ``xmlCharData``, ## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial`` assert(my.kind in {xmlCharData, xmlWhitespace, xmlComment, xmlCData, xmlSpecial}) - return my.a + my.a -proc elementName*(my: var XmlParser): var string {.inline.} = +template elementName*(my: XmlParser): string = ## returns the element name for the events: ``xmlElementStart``, ## ``xmlElementEnd``, ``xmlElementOpen`` assert(my.kind in {xmlElementStart, xmlElementEnd, xmlElementOpen}) - return my.a + my.a -proc entityName*(my: var XmlParser): var string {.inline.} = +template entityName*(my: XmlParser): string = ## returns the entity name for the event: ``xmlEntity`` assert(my.kind == xmlEntity) - return my.a + my.a -proc attrKey*(my: var XmlParser): var string {.inline.} = +template attrKey*(my: XmlParser): string = ## returns the attribute key for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) - return my.a + my.a -proc attrValue*(my: var XmlParser): var string {.inline.} = +template attrValue*(my: XmlParser): string = ## returns the attribute value for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) - return my.b + my.b -proc piName*(my: var XmlParser): var string {.inline.} = +template piName*(my: XmlParser): string = ## returns the processing instruction name for the event ``xmlPI`` assert(my.kind == xmlPI) - return my.a + my.a -proc piRest*(my: var XmlParser): var string {.inline.} = +template piRest*(my: XmlParser): string = ## returns the rest of the processing instruction for the event ``xmlPI`` assert(my.kind == xmlPI) - return my.b + my.b proc rawData*(my: XmlParser): string {.inline.} = ## returns the underlying 'data' string by reference. -- cgit 1.4.1-2-gfad0 From e35e2407575280dc17e121ebcc5fb1578ada6ad0 Mon Sep 17 00:00:00 2001 From: def Date: Thu, 19 Feb 2015 23:28:40 +0100 Subject: parsexml: Use slices instead of copyMem --- lib/pure/parsexml.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index a9fdf87b4..b8f422c31 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -449,7 +449,7 @@ proc parseTag(my: var XmlParser) = my.state = stateAttr # save for later: my.c.setLen(my.a.len) - copyMem(addr my.c[0], addr my.a[0], my.a.len+1) + my.c[0..my.c.high] = my.a[0..my.a.high] else: my.kind = xmlElementStart if my.buf[my.bufpos] == '/' and my.buf[my.bufpos+1] == '>': @@ -626,7 +626,7 @@ proc next*(my: var XmlParser) = my.kind = xmlElementEnd if my.c.len > 0: my.a.setLen(my.c.len) - copyMem(addr my.a[0], addr my.c[0], my.c.len+1) + my.a[0..my.a.high] = my.c[0..my.c.high] of stateError: my.kind = xmlError my.state = stateNormal -- cgit 1.4.1-2-gfad0