En parallèle de l'Analyse XML en Java
Je suis en train d'écrire une application qui traite un lot de fichiers xml (>1000) avec une profonde nœud structures. Il faut environ six secondes avec woodstox (Cas de l'API) pour analyser un fichier avec 22.000 Nœuds.
L'algorithme est placé dans un processus d'interaction de l'utilisateur, où seulement quelques secondes de temps de réponse acceptables. J'ai donc besoin d'améliorer la stratégie pour gérer les fichiers xml.
- Mon processus d'analyse les fichiers xml (extraits seulement quelques nœuds).
- Noeuds extraits sont traités et le nouveau résultat est écrit dans un nouveau flux de données (une copie du document modifié de nœuds).
Maintenant, je suis en train de réfléchir à une multithread solution (qui évolue mieux sur 16 Core+ matériel). J'ai pensé aux stratégies suivantes:
- La création de plusieurs analyseurs et de les exécuter en parallèle sur les sources xml.
- La réécriture de mon algorithme d'analyse d'thread-enregistrer pour utiliser une seule instance de l'analyseur (usines, ...)
- Split de la source XML en morceaux et attribuer les morceaux à plusieurs threads de traitement (réduction de mappage xml - série)
- L'optimisation de mon algorithme (mieux StAX analyseur de woodstox?) /À l'aide d'un analyseur avec construire-dans la simultanéité
Je veux améliorer à la fois, la performance globale et la "fichier" de la performance.
Avez-vous une expérience avec de tels problèmes? Quelle est la meilleure façon de le faire?
- Il n'est pas clair ce que doit être maximisé ici... la performance sur un SEUL fichier, ou le rendement total sur tous les 1000 fichiers.
- Une suggestion: si vous pouvez quantifier la taille des fichiers, afin de permettre le calcul de partout (en mégaoctets par seconde traitées) ça peut donner une idée des performances attendues. En général, je reçois 10 - 40 MO/s pour l'analyse avec Woodstox lors de l'essai; mais mon disque dur ne peut produire de 5 à 10 MO/s vitesse soutenue.
Vous devez vous connecter pour publier un commentaire.
Cela est évidente: il suffit de créer plusieurs analyseurs et de les exécuter en parallèle dans plusieurs threads.
Prendre un coup d'oeil à Woodstox Performance (vers le bas à la moment, essayez de cache de google).
Cela peut être fait SI la structure de votre XML est prévisible: si il a beaucoup des mêmes éléments de niveau supérieur. Par exemple:
Dans ce cas, vous pourriez créer simple diviseur de recherches
<element>
et se nourrit de la présente partie à un analyseur d'instance. C'est une approche simplifiée: dans la vraie vie, j'irais avec RandomAccessFile de trouver des points d'arrêt de début (<element>
) et ensuite créer des FileInputStream que juste opère sur une partie de fichier.Prendre un coup d'oeil à Aalto. Le même gars qui a créé Woodstox. Ce sont des experts dans ce domaine - ne pas réinventer la roue.
Je suis d'accord avec Jim. Je pense que si vous voulez améliorer les performances de l'ensemble de traitement de 1000 fichiers de votre plan est bon, sauf n ° 3 qui n'est pas pertinente dans ce cas.
Cependant, si vous voulez améliorer les performances de l'analyse d'un seul fichier, vous avez un problème. Je ne sais pas comment il est possible de diviser fichier XML sans qu'il l'analyse. Chaque morceau sera illégal XML et votre analyseur va échouer.
Je crois que l'amélioration du temps est assez bon pour vous. Dans ce cas, lire ce tutoriel:
http://download.oracle.com/javase/tutorial/essential/concurrency/index.html
puis créer le pool de thread, par exemple, de 100 threads et la file d'attente qui contient des sources XML. Chaque thread va analyser seulement 10 fichiers qui apportera sérieux avantage en matière de performances en multi-PROCESSEUR de l'environnement.
En plus de bonnes suggestions il y a une chose assez simple à faire: utiliser l'API de curseur (XMLStreamReader), PAS d'Événement de l'API. Événement API ajoute de 30 à 50% de frais généraux sans (juste OMI) a considérablement de faire de traitement easire. En fait, si vous voulez la commodité, je vous conseille d'utiliser StaxMate au lieu de cela; il s'appuie sur le dessus de l'API de Curseur sans l'ajout d'une surcharge importante (au plus 5 à 10% par rapport à la main-code écrit).
Maintenant: je suppose que vous avez fait de base, les optimisations Woodstox; mais si pas, découvrez "3 Règles Simples pour Rapide XML-traitement à l'aide de Stax". Plus précisément, vous devrait absolument:
La raison pour laquelle je mentionne cela est que, bien que ceux-ci font aucune différence fonctionnelle (code fonctionne comme prévu) ils peuvent faire de grandes différences de performances; bien plus, donc, lors du traitement des fichiers plus petits.
L'exécution de plusieurs instances ne font sens; bien que généralement avec au plus 1 thread par core. Toutefois, vous obtiendrez uniquement des prestations aussi longtemps que vos e/S de stockage peuvent soutenir de telles vitesses; si le disque est le goulot d'étranglement cela n'aidera pas et peuvent, dans certains cas, de mal (si le disque cherche concurrence). Mais il vaut la peine d'essayer.