8
votes

Améliorer les performances de xmlSerializer

J'utilise un xmlSerializer pour sérialiser / désérialiser certains objets. Le problème est la performance. Lors du profilage, en utilisant le xmlSerializer Faites notre application 2 secondes de plus pour démarrer. Nous mettons en cache notre xmlserializer et les réutiliserons. Nous ne pouvons pas utiliser sgen.exe car nous créons le XMLSerializer avec xmlattributeoverrides .

J'essaie d'utiliser une alternative de sérialisation comme JSON.NET et, au début, cela fonctionne bien. Le problème est que nous devons être compatibles vers l'arrière afin que tous les XML déjà générés doivent être analysés correctement. En outre, la sortie de sérialisation de l'objet doit être XML.

résumer:

  1. Je reçois des données XML sérialisées par un XMLSerializer.
  2. J'ai besoin de désérialiser les données XML et de le convertir en un objet.
  3. J'ai besoin de sérialiser l'objet dans XML (idéalement un format XML comme celui d'un XMLSerializer aurait fait)

9 commentaires

Vos données XML contiennent une balise d'ouverture et la fermeture de la balise . Je suppose que c'est une erreur de frappe. De plus, dans votre question, vous définissez le format des données d'entrée, mais pas clair définit le format de la sortie JSON. Comme vous pouvez représenter exactement les mêmes informations de différents formats XML, vous pouvez produire différentes données JSON avec l'ensemble d'informations équivalentes, mais différents formats. Je pense que vous devriez définir plus d'effacer le format des données de sortie.


Ce serait bien si vous effacez également la restriction "Je ne peux pas utiliser un xmlSerializer". Si la raison n'est que la performance, il existe alors de nombreuses façons d'améliorer les performances, à l'aide de sgen.exe ou en implémentant l'interface iserializable . Quelle est la plus difficile dans la question: pourquoi vous avez un format d'entrée si étrange si les données. Avez-vous un long fichier XML ou vous avez beaucoup de fichiers de ce type? Typiquement, on dispose des informations d'origine dans la base de données. Alors pourquoi vous avez besoin d'une entrée XML étrange au lieu d'accéder aux données originales ?


Je tiens à mettre à jour ma question à plus représenter par problématique


N'est-ce que seulement un problème de démarrage avec le XMLSerializer? Comme oleg dit, le temps de sérialisation / désérialisation peut être assez rapide (il est compilé) s'il est utilisé correctement, par exemple si les bons constructeurs sont appelés, etc.


Oui, ce n'est qu'au démarrage car au démarrage, nous désoriens nos objets. Ce qui prend le temps consiste à construire le XMLSerializer. Après, il est assez rapide mais nous devons améliorer notre heure de démarrage.


Pourriez-vous désérialiser sur un fil de fond au démarrage afin qu'il semblerait plus rapide pour vos utilisateurs.


Vous pouvez également utiliser JSON & XML côte à côte. Si le fichier JSON existe, chargez-le, sinon charge le fichier XML. Bien sûr, vous devez sauver XML & JSON lorsque certaines mises à jour sont nécessaires.


@Oleg iserializable n'est pas liée à la question


@Marcgravell: merci! C'était en tapant une erreur. Je veux dire ixmlSerializable de cause.


6 Réponses :


0
votes

Vous devez désérialiser votre liste à l'aide d'une sérialisation classique .NET

quelque chose comme ci-dessous: xxx

alors vous pouvez utiliser le JSON.Serialization xxx


1 commentaires

Je ne peux pas utiliser le fichier XMLSéraliseur .NET, car dans notre projet, il a une mauvaise performance. C'est pourquoi j'essaie d'utiliser le jsonsérializer, mais je dois être compatible avec notre ancien format, donc j'ai besoin de gérer XML sérialisé par XMLSerializer sans utiliser de xmlSerializer ...



0
votes

Si XML stocké est stocké dans le format que vous ne pouvez pas utiliser, utilisez XSLT pour le transformer au format que vous pouvez utiliser.

Si ce XML est stocké au format XMLSerializer - disons dans des fichiers plats - ou un dB - alors vous pouvez exécuter vos transformations sur elle une fois et ne pas inciter la surcharge XMLSerializer à votre heure d'exécution habituelle.

Alternativement, vous pourriez le xslt le temps d'exécution - mais je doute que cela soit plus rapide que la méthode décrite par Massimiliano.


0 commentaires

0
votes

Cette Réponse a de bonnes informations sur lesquelles XMLSerializer est lent avec XmlattributeOverrides.

Avez-vous vraiment besoin d'utiliser le xmlSerializer dans votre fil principal au démarrage?

Peut-être l'exécuter dans un fil de fond; Si seulement certaines parties des données sont obligatoires pour la startup, vous pouvez peut-être les lire manuellement dans des versions proxy / clairsemées des classes réelles tandis que le XMLSerializer Initialise.

Si c'est une application d'interface graphique, vous pouvez simplement ajouter un écran éclaboussable pour masquer le délai (ou une partie de tetris !!)

Si tout le reste échoue, vous ne pouvez pas convertir les fichiers existants en JSON en exécutant simplement le désériialize existant et un JSON Serialize, ou y a-t-il une obligation difficile de les garder xml?


0 commentaires

0
votes

Vous pouvez utiliser le filetage ou les tâches pour obtenir l'application au démarrage plus rapide et n'attendez pas la hardrive ou la désérialisation.


0 commentaires

2
votes

Le problème est que vous demandez des types qui ne sont pas couverts par SGEN, ce qui entraîne la génération de nouveaux assemblys lors du démarrage.

Vous pouvez essayer de mettre la main sur les fichiers temporaires générés par XMLSerializer pour vos types spécifiques et utilisez ce code pour votre propre ensemble XMLSerializer Pregnerated. J'ai utilisé cette a été exécuté qui a retardé le démarrage de ma demande.

En plus de cela, cela pourrait aider à renommer des types comme dans l'article pour arriver aux mêmes noms de type que SGen crée pour pouvoir utiliser SGen. Les tableaux de type généralement ne sont pas précréés par SGen, ce qui est parfois un pupitre. Mais si vous nommez votre classe Arrayof ICIGOESYOURTYPENAME, vous pourrez utiliser les assemblys prégéniés.


0 commentaires

11
votes

En fin de compte, cela dépend de la complexité de votre modèle. XMLSerializer doit faire beaucoup de pensée et le fait que cela me conduise si longtemps me conduit à soupçonner que votre modèle est assez complexe. Pour un modèle simple , il pourrait être possible d'implémenter manuellement la désérialisation à l'aide de LINQ-TO-XML (assez simple) ou peut-être même xmlreader (si vous vous sentez très courageux - il n'est pas facile d'obtenir 100% correct).

Toutefois, si le modèle est complexe, il s'agit d'un problème et franchement serait très risqué en termes d'introduction de bugs subtils.

Une autre option est une autre option DatacontractSerializer qui gère XML, mais pas aussi bien que xmlSerializer , et certainement pas avec autant de contrôle sur la mise en page. Je soupçonne fortement que DatacontractSerializer ne vous aiderait pas.

Il n'y a pas de remplacement direct pour xmlserializer que je suis au courant, et si Sgén.exe n'est pas une option, je pense que vous avez essentiellement des options:

  • vivre avec elle
  • réécrit xmlSerializer vous-même, en quelque sorte mieux que celles-ci
  • Utilisez quelque chose comme LINQ-TO-XML et accepter l'effort impliqué

    long terme, je dirais des "formats de commutation" et utilisez uniquement XML pour l'importation héritée uniquement. Je connais de certains protocoles binaires très rapides qui seraient assez faciles à remplacer; p


1 commentaires

Excellente réponse. Je devais faire quelque chose de similaire dans un projet où je devais utiliser des interfaces et ne pas utiliser de classes abstraites (car c # ne fait pas de multiples héritage). Utiliser LINQ vers XML et la réflexion ont fait l'affaire. Ma prochaine tâche consiste à faire des attributs au lieu d'une liste de règles dans les paramètres (vient d'apprendre à ce sujet). Je dois dire que c'est beaucoup de plaisir.