DataGrid Performance - how to read 2,000 XML records in less than half a second
Traduire/Translate : French - Espagnol - Deutsch (by Google)
The problem
Question : What is the fastest way to read 2,000 XML records in order to display them in a DataGrid?
Here are four different methods with their performances on the same system:
Method 1 (regular) Nodes, XMLConnector with Schema and Databinding |
Method 2 Attributes, XMLConnector with Schema and DataBinding |
Method 3 Attributes, parse XML and dataProvider |
Method 4 Attributes, parse XML and items |
|
Flash Player 7 | 12 388 ms | 11 963 ms | 2 930 ms | 442 ms |
Flash Player 8 | 9 365 ms | 7 569 ms | 1 858 ms | 314 ms |
Closer look at the problem
In many forums, users complain about the performances of the XMLConnector, DataSet and DataGrid trio for when reading large XML files.
This article compares 4 different methods for reading un XML file with 2,000 records.
The test
The file contains 2,000 records representing clients.
A client is described by a lastname (nom inFrench), a firstname (prenom in French), an age, a town (ville in French) and a turnover (ca in French). Data are typed String and Number.
The goal is to read all the data stored in an XML file as fast as possible, display the records in a DataGrid and select the third line.
dgperfSrc.zip (1 696 Ko)
Method 1
To represent the data, we use nodes. Here is how a particular client is described:
<client>
<lastname>Deschamps</lastname>
<firstname>Amandine</firstname>
<town>Caluire-Et-Cuire</town>
<age>43</age>
<turnover>2173.7</turnover>
</client>
In Flash, we use an XMLConnector to read the file - with a Schema -, a DataSet for the model and a DataGrid to display the records. We use 3 DataBindings to link the 3 elements.
It's the 'classical' method found in many tutorials.
Why is this method slow?
The XML file is 315 kb. When a Schema is used with an XMLConnector, Flash applies an XPath to access the data.
The file is big and an XPath is slow. It's the slowest method. It takes 12.5 seconds on the test system.
The test
Wait for about 12.5 seconds (with Flash Player 7)...
Method 2
The idea behind this method is to use attributes instead of nodes and see the impact on the performances.
Here is how a particular client is described:
<client lastname="Deschamps" name="Amandine" town="Caluire-Et-Cuire" age="43" turnover="2173.7"/>
In Flash, we use the same method as in method 1: an XMLConnector to read the file - importing the schema-, a DataSet and DataGrid. We have 3 DataBindings to link the 3 elements.
Why is this method faster than method 1?
The XPath is faster when accessing attributs. The XML file is also smaller - 164 kb instead of 315 kb.
The test
Wait 12 seconds...
Method 3
To represent data, we use attributs.
The idea is to drop the XMLConnector, which uses an XPath, and directly parse the XML.
To do this, we use nextSibling in a while loop. To encode numbers, we use Number (and parseInt and parseFloat which are slower).
There is no DataBinding between an XMLConnector and a DataSet. We use the dataProvider of the DataSet to link the result of the XML parsing.
Why is this method faster than method 2?
We parse the XML file directly. XPath isn't used and there is no Schema in XMLConnector.
On the other hand, attributs must be encoded. In most cases, XML data are strings and converting numbers is fast.
The test
Wait for 3 seconds...
Method 4
In method 3, we found out to read XML fast. The idea behind this method is to improve the link to the data (method 3 uses a DataProvider).
The documentation says there are 2 ways to associate data to a DataSet: using a dataProvider or items.
What is the difference between these two?
The documentation of Flash MX 2004 or Flash 8 and the LiveDocs don't go into details. Reading the source code of a DataSet (Macromedia\Flash 8\en\First Run\Classes\mx\data\components\DataSet.as), we learn that using a dataProvider, types are converted if there is a schema (see internalAddItem) when items do a direct link with no type checking or conversion. Since our code converts data if necessary, using items is all right.
Here is the code:
client_con.addEventListener("result", Delegate.create(this, doParseData));
//
function doParseData():Void {
var dataXML:XML = client_con.results;
var resultArray:Array = [];
var mainNode = dataXML.firstChild;
var aNode:XMLNode = mainNode.firstChild;
while (aNode) {
var obj = new Object();
for (var attribute:String in aNode.attributes) {
if (attribute == "age" || attribute == "turnover") {
obj[attribute] = Number(aNode.attributes[attribute]);
} else {
obj[attribute] = aNode.attributes[attribute];
}
}
resultArray.push(obj);
aNode = aNode.nextSibling;
}
// -- use items (and not dataProvider)
client_ds.items = resultArray;
}
This method reduces the time it takes to read an XML file with 2.000 entries from 12.5 seconds to less than 0.5 second.
The test
Wait half a second...
Comments
Flash Player 7 / Flash Player 8
The tests shows that the new Flash Player 8 is 40% faster.
Drawbacks
Attributes must be encoded but in most cases data types are simple and are easy to convert. For date or other types, contact me.
Using XML files with nodes and attributs
A solution is to apply an XSL transformation (XSLT) on the server to replace nodes by attributs.
dgperfSrc.zip (1 696 Ko)
Version
version 1.0 - 23-Oct-2005 : initial revision