I'm writing an own class to parse some xml documents. Therefore I use libxml. I created a XMLDocument class and a XMLNode class. I wrote some functions like "elementsForName" and so on. In the end the whole project running on the iPad 3 was extremely slow, when I parse huge xml documents. I tried to find out with the 'Time Profiler' of 'Instruments', where the problem is.
The problem is the way, how Swift works with Arrays. I have a function called func elementsForName(name: String) -> [MyXMLNode]? {
. In this method I loop through all children nodes of the given node. I compare the node type and the node name. If it's the same as the 'name'-String, I create a new instance of my MyXMLNode-class and append it to an array. The problem is, that appending to an array will resize the array, so Swift will copy the whole array. This needs a lot of time in the end. (I found this useful thread: Swift vs Java - speed at filling big array)
Here my method:
func elementsForName(name: String) -> [MyXMLNode]? {
var children = [MyXMLNode]()
var currentNode = nodePointer!.memory.children
while currentNode != nil {
let tag = String.fromCString(CString(UnsafePointer<xmlChar>(currentNode.memory.name)))
if currentNode.memory.type.value == 1 && tag == name {
children.append(MyXMLNode(xmlNodePointer: currentNode))
}
currentNode = currentNode.memory.next
}
if children.count == 0 {
return nil
}
return children
}
I thought about creating an array with a given capacity, but before ending the loop, I cannot know, how much elements of the given name will be found.
Any ideas?