Building XML
The Flash API provides a very nice set of XML classes along with syntax sugar in its E4X implementation. You can use this to not only read XML that you download, but also to write out XML that you upload. Unfortunately, it turns out that this is horrifyingly slow. Today we’ll do a little experiment to exemplify this.
The XML, its sister class XMLNode, and the many E4x syntax sugar operators AS3 provides for you sure do make using XML clean, clear, and easy. In addition to the ease-of-use functionality, you get the flexibility of simply changing your pretty printing, easy reading back from your written XML, and a lot more flexibility to insert content wherever you need it. But let’s see the cost of all this with a simple test app:
const NUM_STUDENTS:int = 1000; var i:int; var beforeTime:int = getTimer(); var studentsXML:XML = <students/>; for (i = 0; i < NUM_STUDENTS; ++i) { var student:XML = <student/>; var firstName:XML = <firstName/> firstName.appendChild("First"+i); student.appendChild(firstName); var lastName:XML = <lastName/>; lastName.appendChild("Last"+i); student.appendChild(lastName); studentsXML.appendChild(student); } trace("XML Class Time: " + (getTimer()-beforeTime)); beforeTime = getTimer(); var studentsString:String = "<students>\n"; for (i = 0; i < NUM_STUDENTS; ++i) { studentsString += " <student>\n <firstName>First" + i + "</firstName>\n <lastName>Last" + i + "</lastName>\n </student>\n"; } studentsString += "</students>"; trace("String Class Time: " + (getTimer()-beforeTime));
This simply builds a list of students using the XML and String classes, such as the list of students that may reasonably attend a middle school: 1000. If you’re used to seeing my test applications, you’re probably used to seeing huge numbers for the sake of amplifying performance differences. Unfortunately, the performance is so bad here that no such amplification was required:
Environment | XML Class | String Class | Slowdown |
---|---|---|---|
2.2 Ghz Intel Core 2 Duo, 2GB RAM, Mac OS X 10.6 | 369 | 2 | 184.5x |
3.0 Ghz Intel Core 2 Duo, 4GB RAM, Windows XP | 229 | 1 | 229x |
Average | 206.75x |
Ouch! Using the XML class to build even a simple XML file as this is over 200x slower than plain Strings! If you’re interested at all in performance, even in a non-critical part of your code, avoid using the XML class to build your XML. On a slower computer than mine, this may cause a full second skip in any animation or UI interaction, which is usually deemed unacceptable. If you absolutely must use the XML class to build your XML, you’ll need to really start adding complexity by splitting the creation across frames of animation. This will likely further widen the performance gap. Meanwhile, the lowly String class can build this XML document in a snap without any complications. It is clean and straightforward to implement with a String. So watch out for the XML class. It can be deadly slow.
#1 by jonathan on October 19th, 2009 ·
Have you try :
It does the same result but without large call of functions.
#2 by jackson on October 19th, 2009 ·
I cleaned up your posts (I don’t know how to put XML in comments either, but I’ll look into it) and tried out your version on the Windows environment I added to the article. The difference seemed negligible: 225-235ms compared to 229. Still, it’s a lot cleaner way of doing it, especially for this simple example.
Thanks for the tip!
#3 by jonathan on October 19th, 2009 ·
sorry can you clean my posts, I don’t how to post XML under actionscript…
#4 by Jonnie on October 19th, 2009 ·
I’d be curious to see what the result is for the String route if you parse it to XML at the end: var $xml:XML = new XML (studentsString);
#5 by jackson on October 19th, 2009 ·
I thought of converting the string to XML and the XML to string, but decided to keep the test pure. After all, sometimes you want the string and sometimes you want the XML, so there is no universal goal that both approaches should go toward. But you showed some interest so I tried it out. It didn’t make any significant difference in either time. I’m still seeing the exact same numbers as I listed in the article. Still, it’s good to know that these conversions are fast!
#6 by mels on October 20th, 2009 ·
FYI :
XML Class Time: 564
String Class Time: 3
XML Class from String Time: 13
(var $xml:XML = new XML (studentsString);)
#7 by jackson on October 20th, 2009 ·
Interesting. Would you mind posting your test environment (specs, OS, Flash player)?
#8 by mels on October 21st, 2009 ·
1.7 Ghz Intel , 1GB RAM (?), Windows XP, flash player WIN 10,0,32,18
#9 by anon-anon on November 27th, 2009 ·
You may want to look at vtd-xml as the state of the art in XML processing, consuming far less memory than DOM
http://vtd-xml.sf.net
#10 by jackson on November 29th, 2009 ·
Unfortunately it’s not available in AS3, AS2, or JavaScript. Maybe one day there will be a port.
#11 by skyboy on February 27th, 2012 ·
I attempted to find an article where you tested the speed of concatenating strings, but this is the most relevant I found via search. You should run an article showing the difference between
str += str
,str += "data"
, andbuffer.writeUTFBytes(str)
. I believe that in v11 the former has been sped up to more closely match the latter; though I’m uncertain (something you could cover). For single characters there’s alsobuffer[inx] = charCode
and writeByte (anything over 0x7F requires UTF-8 encoding to be applied manually). I’ve also written a StringBuffer class similar to what you’d find in a language like Java.#12 by jackson on February 27th, 2012 ·
I also mentioned it in Hidden Object Allocations, but you’re right that I’ve never explicitly tested the performance. It’s a great idea though so I’ll add it to my list. Thanks for the tip!