Question de tous les codeurs Flex : Quel est le moyen le plus rapide pour lire de gros fichiers de données XML et les afficher dans un DataGrid ?Voici les quatre méthodes utilisables et leurs performances sur une machine…Source : http://philflash.inway.fr/dgperf/index.html
| Méthode 1 (classique)Noeuds, XMLConnector avec Schéma et Databinding | Méthode 2Attributs, XMLConnector avec Schéma et DataBinding | Méthode 3 Attributs, parse XML et dataProvider | Méthode 4Attributs, parse XML et 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 |
Le problème détaillé
Dans de nombreux utilisateurs se plaignent des performances de flex pour lire des fichiers XML.Voici le classement des 4 méthodes :
Méthode 1
Pour représenter les données, nous utilisons des noeuds. Un client est représenté de la manière suivante :<client><nom>Deschamps</nom><prenom>Amandine</prenom><ville>Caluire-Et-Cuire</ville><age>43</age><ca>2173.7</ca></client>Pour Flash, nous utilisons un XMLConnector pour lire le fichier (en utilisant un Schéma), un DataSet pour le modèle et un DataGrid pour afficher les données. On utilise des liaisons de données (DataBinding) pour lier les 3 éléments.C’est la méthode “classique” que vous trouverez dans de nombreux tutorials.
Pourquoi cette méthode est lente ?
Le fichier XML a une taille de 315 ko. Lorsqu’on utilise le Schema d’un XMLConnector, Flash utilise un XPath pour accéder aux données.Le fichier est gros, le XPath est lent : c’est la méthode la plus longue. On arrive à 12,5 secondes.
Méthode 2
L’idée de cette méthode est d’utiliser des attributs (au lieu des noeuds) et de voir l’impact sur les performances.Un client est représenté de la manière suivante :<client nom="Deschamps" prenom="Amandine" ville="Caluire-Et-Cuire" age="43" ca="2173.7"/> Pour Flash, nous utilisons la même méthode que dans la méthode 1 : un XMLConnector pour lire le fichier (en important le schéma), un DataSet comme modèle et un DataGrid pour afficher les données. On utilise des liaisons de données (DataBinding) pour lier les 3 éléments.
Pourquoi cette méthode est plus rapide que la méthode 1 ?
Le XPath est plus “rapide” pour accéder à un attribut (que pour un noeud). Notons aussi que le fichier XML est plus “petit” (164 ko au lieu de 315 ko). La durée est d’environ 12 secondes…
Méthode 3
Pour représenter les données, nous utilisons des attributs.L’idée de cette méthode est de ne pas utiliser le schéma du XMLConnector (qui utilise un XPath) mais de parser manuellement le XML.Pour ceci, on lit le plus “rapidement” le XML : on utilise une boucle while avec nextSibling. Pour encoder les nombres, on utilise Number (et non pas parseInt et parseFloat qui sont plus lents).Il n’y a plus de databinding entre le XMLConnector et le Dataset. On utilise le dataProvider du DataSet pour lier le résultat du parsing du XML.
Pourquoi cette méthode est plus rapide que la méthode 2 ?
On effectue manuellement le parsing du XML. On n’utilise plus le XPath (et on n’utilise pas le Schema du XMLConnector).Par contre, il faut “encoder” les attributs. Dans la plupart des données XML, on retrouve des chaînes de caractères et des nombres. L’encodage est donc très rapide. Le test dure 3 secondes.
Méthode 4
Avec la méthode 3, on sait lire très rapidement le XML. L’idée de cette méthode est de savoir si on peut améliorer la liaison de données (on utilise dataProvider dans la méthode 3).Si vous regardez la documentation du DataSet, il existe deux méthodes pour associer des données à un DataSet : la méthode dataProvider et la méthode items.Quelle est la différence entre dataProvider et items ?La documentation de Flash MX 2004, de Flash 8 ou des LiveDocs ne donne pas trop de détails. Il faut donc regarder les sources du DataSet :Dans Flash 8 : Macromedia\Flash 8\en\First Run\Classes\mx\data\components\DataSet.asEn fait, la méthode dataProvider effectue des conversions de type si il existe un Schema (dans la méthode internalAddItem). La méthode items effectue un lien direct (sans conversion/vérification de type).Comme on a déjà effectué les conversions de type, on utilise donc la méthode items. (Dans la méthode 3, la conversion de type n’était pas nécessaire).Le code est le suivant :
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 == “ca”) {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;}
Voila une méthode qui permet de passer de 12,5 secondes à moins de 0,5 secondes pour lire un fichier de 2 000 enregistrements !
Si vous venez pour la première fois sur Flex-Info.fr, vous pouvez vous abonner à mon Twitter http://twitter.com/flexinfo ou au flux RSS. Merci pour votre visite !













juin 14th, 2008 Ã 13 h 04 min
Salut
Je vois que c’est une bonne méthode, mais serais tu la mettre en place dans un projet flex. Moi je n’y arrive pas !
avril 21st, 2009 Ã 10 h 23 min
Un code générique sera toujours plus lent qu’un code optimisé pour ton cas d’application. Donc évidement que la méthode 4 est + rapide que les autres, mais il faut aussi comparer la facilité d’utilisation!
septembre 8th, 2010 Ã 14 h 35 min
L’idéal est d’aussi activer la compression gzip des fichiers xml (module gzip d’apache ou deflate htaccess, ou dans les param. IIS). La majorité des navigateurs gèrent la décompression et le gain de bande passante (et donc de récupération des data) est conséquent
septembre 8th, 2010 Ã 18 h 40 min
C’est clair que le GZIP est conseiller dans les headers que lors des requêtes.