Au travail, nous utilisons un fichier journal XML. Chaque message journal est un bloc Pour les fichiers journaux de taille moyenne (environ 2 Mo) , nous avons eu des problèmes de performance (jusqu'à une minute de chargement du XML et de faire des manipulations de base) et je pourrais les réduire à un projet de test comme celui-ci (Modifier: Mise à jour du code et des mesures ajoutées): P>
Code> Construit et ainsi de suite et le fichier journal peut être transformé en HTML localisé à l'aide du traitement Delphi et XSLT ultérieurement.
Node count 8000 10000 12500 15625 19531 24413 30516 38145 47681
Base test time 484 781 1140 1875 2890 4421 6734 10672 16812
Variation 1 32 47 62 78 78 141
Variation 2 2656 3157 3906 5015 6532 8922 12140 17391 24985
(delta Base) 2172 2376 2766 3140 3642 4501 5406 6719 8173
4 Réponses :
Je suis d'accord avec MJ2008 que XML n'est pas un bon ajustement pour la journalisation. Cela dit, ce problème et de grands fichiers XML en général peuvent être traités plus rapidement en utilisant SAX , il lance des événements lors de l'analyse du flux entrant de données XML, ce qui vous permet de traiter les éléments tels qu'ils sont lus à partir du disque, en atténuation de l'exponentialité du chargement de la mémoire en mémoire avant le remettre à xslt. p>
Je regrette que je n'ai pas fait SAX dans Delphi (encore), mais je soupçonne que la partie la plus difficile implémente les interfaces saxoques requises (par exemple, IsaxContHandler ), mais Delphi a TinterfaCedObject et TautoObject et d'autres pour cela. P>
Cette réponse me confond encore plus. Vous dites que SAX améliore la performance que je comprends parfaitement, mais pourquoi a-t-il toujours des heures d'exécution exponentielle lors du chargement? Quelle est la raison pour analyser la seconde moitié des nœuds x prend deux fois plus longtemps que la première moitié? Je le comprendrais peut-être pour un pire des cas xml arborescence (noeuds nichés x), mais pour la structure simple d'un fichier journal (x des nœuds de message séparé), le temps d'exécution non linéaire semble faux.
L'analyse de SAX va échouer linéairement avec la taille du fichier d'entrée
Je vais juste faire confiance à David pour maintenant et +1 et accepter votre réponse car SAX aurait été l'une des choses que j'aurais essayé ensuite. Si cela a aussi un comportement exponentiel, je posterai une nouvelle question ou modifierai celui-ci, mais j'en doute. Merci!
Votre question en un mot: pourquoi la bibliothèque binaire msxml est-elle si lente? Qui sait. On s'en fout. Allez-vous le désassembler? Casser à Microsoft et saisir son code source? Ce n'est pas Delphi ici, c'est le code Microsoft. P>
Bien que XML est un mauvais choix pour la journalisation, Omnixml est probablement un meilleur choix que MSXML. P>
Cependant, un choix bien meilleur est appelé "Fichier texte ouvert pour l'annexe, Ligne d'écriture, Fermer le fichier texte". Notez l'évolutivité inhérente et le manque d'analyse requise. P>
+1 parce que vous avez absolument raison, et ce que j'ai fait pour résoudre les problèmes dans ces directions. J'étais juste des curiosités si quelqu'un ici est peut-être aussi connu la réponse. BTW, je suis assez proche d'inspecter / désassembler ou du moins de faire des recherches supplémentaires sur le sujet, car je m'intéresse pourquoi / comment ils ont vissé msxml up si mauvais.
Utilisez-vous le terme "exponentiel" dans un sens mathématique, ou juste dans un sens populaire? Il serait intéressant de savoir, par exemple, que ce soit vraiment quadratique, ou s'il s'agit d'une sorte de fonction où la performance est relativement linéaire jusqu'à ce que vous frappiez un seuil (taille de la mémoire) auquel cela se dégrade soudainement. P>
Si cela prend une minute pour traiter 2 Mo, alors quelque chose est très mal faux. Je ne connais pas votre environnement assez bien pour commencer à deviner, mais cela devrait prendre au plus une seconde. Vous devez explorer pour trouver où se passe le moment. Commencez par établir si elle dépense son temps à l'analyse du XML, ou le traitement du XML après l'analyse est terminé. P>
Je mettrai à jour la question avec le code complet, les exécutions et l'utilisation de la mémoire bientôt. J'utilise "exponentiel" dans un sens mathématique, par ex. Pour une "base" XML 10 Ko de taille, le traitement 20 Ko prend environ 4 fois plus longtemps, 40 Ko prend environ 16 fois plus longtemps et ainsi de suite. Mais votre question est toujours valide, car je n'ai coché que 3-5 valeurs la dernière fois et n'a pas fait une analyse complète d'exécution.
Ce serait une échelle quadratique. Êtes-vous par hasard à l'aide de Bubble Tri?
@DavidHeffernan: Je ne fais rien qui expliquerait le comportement quadratique, c'est pourquoi je suis si intéressé par la raison ou ce que MSXML va mal ici. Je peux même réduire le problème à deux appels d'API, charger un XML et compter ses nœuds.
Quelle partie de celle-ci est quadratique? Chargement ou comptage?
Compter, mais cela ne dépend pas si je compte les nœuds ou effectuez une autre opération sur le XML, il semble qu'il y ait une initialisation / validation retardée en cours et les opérations après cela montrant un comportement "normal" attendu.
Contrairement aux commentaires des autres, je pense que XML est un excellent format de journalisation. Les wrappers Delphi VCL pour XML sont très métisseurs de mémoire gourmands. Cela peut donc expliquer la performance médiocre du traitement pure txmldocument à l'échelle.
Je recommanderais plutôt de publier sur votre journal XML en utilisant une simple transformation XSLT. Je n'ai pas mesuré la performance de cette solution à l'échelle, mais je pense que ce sera une vaste amélioration de ce que vous rapportez actuellement. P>
Par exemple Supposons que notre journal ait quelque chose comme ça ... p> Cette simple feuille de style XSLT 1.0, avec paramètre ... ajoutera un message au journal. p> pour atteindre cet objectif dans Delphi, utilisez le Après des déclarations ... p> créer une itransform, passant dans la feuille de style comme une chaîne. Définissez les deux propriétés de nom de fichier au nom de fichier du journal. Chaque fois que vous devez ajouter un message au journal, appelez Une implémentation possible pour la liaison de langue susmentionnée peut être ... p> Ceci se lie à MS MS XML Bibliothèque de Microsoft et moteur XSLT. Malheureusement, je ne connais aucun moyen pratique de lier Processeur XSLT de Saxon à Delphi Code . P> Une mise en œuvre alternative pour tirer parti de MSS XSLT Le moteur est donné par Ma réponse ici . L'inconvénient de cette méthode est que la paramétrage n'est pas indigène. Pour paramétrer la feuille de style, vous devriez rouler le vôtre, en effectuant une chaîne Remplacer sur la feuille de style avant la transformation. P> Si vous faites beaucoup de journalisation rapidement Cela peut être une bonne stratégie pour mettre en cache les messages à enregistrer la mémoire, puis à intervalles réguliers mais pas trop fréquents, purge votre cache avec une seule transformation XSLT pour écrire tous vos messages. P> P> addend-message code> ... < / p>
la liaison de langue h2>
addparameter () code>, puis
transformer () code>. P>
Détails de la mise en œuvre de la solution h2>
Mise en œuvre alternative H2>
Considérations de performance h2>
+1, légèrement offtopique alors que la journalisation elle-même n'est pas mon problème, mais c'est un bon moyen de faire le principal travail de journalisation.
+1 pour une idée folle. Je pense toujours que cela souffre de trop de complexité. Les fichiers texte sont meilleurs.
Ce n'est pas vraiment un problème Delphi. Les routines XML en question sont simplement une interface avec la bibliothèque Standard
MSXML CODE> MSXML Windows.
XML n'est pas bon pour la journalisation. La meilleure option que vous avez est d'ouvrir le fichier, de localiser la dernière balise (espérons-le automatiquement automatiquement par la taille connue, appendez vos nouveaux nœuds, puis appendez à nouveau la dernière balise. Sinon que vous êtes sur un perdant.
@ Masonwheeler: Merci d'avoir souligné cela, bien que je sache et cela change simplement le bouc émissaire. La question reste donc la même.
@ MJ2008: Ajout de nouveaux messages est effectué comme si vous avez décrit et que le fichier journal est uniquement chargé dans son ensemble lors de la convertie en HTML, le problème n'affecte donc pas le processus de journalisation principal. Néanmoins, XML présente des avantages ici comme mentionné, par ex. XSLT est très utile et tout ce qui est utilisé dans le flux de travail est "UTF prêt".
Avez-vous essayé de mesurer le temps de ce code? Je pense que la plupart du temps est dépensé pour
loadfromfile () code>. Je vous recommande de regarder
nativexml code> et
omnixml code> analyseurs.
@Teran: J'ai fait des mesures il y a quelques mois et je pourrais éditer la question demain après les avoir examinées, mais afaire un seul
Chargéfromfile () code> appel sans autre modification XML était très rapide et ne fait que lentement lorsque Ajout de modifications (et seule la première modification est lente), il semble donc utiliser l'initialisation / validation retardée.
Les API basées sur DOM @schnaader sont toujours faciles à utiliser, mais lentement. D'autre part, les API de SAX sont assez difficiles à travailler, mais rapides.
Mise à jour de la question avec des mesures de code et de temps complets, a également changé «exponentiel» à «quadratique» pour clarification.