Maison  >  Article  >  développement back-end  >  Comparaison des performances des méthodes de lecture de données XML (2)

Comparaison des performances des méthodes de lecture de données XML (2)

黄舟
黄舟original
2017-02-13 15:45:241730parcourir

En parlant de ça, le dernier numéro résumait la méthode générale de lecture XML, mais généralement nous n'utilisons pas nécessairement toutes les données de la source XML, j'ai donc expérimenté la lecture de certaines données, comme la position basée sur la première lettre du titre.

Pour les trois méthodes de lecture aléatoire, il vous suffit de modifier les conditions de requête

 

XmlDocument:
var nodeList = doc.DocumentElement.SelectNodes("item[substring(title,1,1)='M'][position() mod 10 = 0]");
  XPathNavigator:
var nodeList = nav.Select("/channel/item[substring(title,1,1)='M'][position() mod 10 = 0]");
  Xml Linq:
var nodelist = from node in xd.XPathSelectElements("/channel/item[substring(title,1,1)='M'][position() mod 10 = 0]")

En utilisant XPath, il vous suffit de modifier une seule ligne de code. XPath est également assez facile à maîtriser, bien plus simple que SQL. Vous pouvez vous référer à l'introduction à la syntaxe du W3C Shcool et au LINQ To XML de MSDN pour les utilisateurs XPath, et vous pourrez maîtriser les secrets en un quart d'heure.

Mais pour la méthode XmlReader, ce n'est pas si simple. Elle lit aussi le titre commençant par M, et sélectionne un élément sur dix. Après avoir longuement réfléchi, je n'ai pas trouvé d'élément. implémentation élégante, j'ai donc dû faire ceci :

Code

static List<Channel> testXmlReader2()
{
    var lstChannel = new List<Channel>();
    var reader = XmlReader.Create(xmlStream);
    int n = 0;Channel channel = null;
Search:
    while (reader.Read())
    {
        if (reader.Name == "item" && reader.NodeType == XmlNodeType.Element)
        {  
            while (reader.Read())
            {
                if (reader.Name == "item") break;
                if (reader.NodeType != XmlNodeType.Element) continue;
                switch (reader.Name)
                {
                    case "title":
                        var title = reader.ReadString();
                        if (title[0] != &#39;M&#39;) goto Search;          
                        n++;
                        if (n % 10 != 0) goto Search; 
                        channel = new Channel();
                        channel.Title = title;
                        break;
                    case "link":
                        channel.Link = reader.ReadString();
                        break;
                    case "description":
                        channel.Description = reader.ReadString();
                        break;
                    case "content":
                        channel.Content = reader.ReadString();
                        break;
                    case "pubDate":
                        channel.PubDate = reader.ReadString();
                        break;
                    case "author":
                        channel.Author = reader.ReadString();
                        break;
                    case "category":
                        channel.Category = reader.ReadString();
                        break;
                    default:
                        break;
                }
                lstChannel.Add(channel);
            }
        }
    }
    return lstChannel;
}

 Comme vous pouvez le voir, la structure du code a considérablement changé. Afin d'effectuer un filtrage conditionnel, j'ai dû ajouter une variable locale n, ajuster l'initialisation de la classe d'entité et ajouter l'emplacement de l'instruction de collecte. J'ai même été obligé d'utiliser l'instruction goto que j'avais oubliée pendant de nombreuses années pour sauter. (VB c'est mieux). La logique métier s'infiltre dans la mise en œuvre des détails du code. Selon les mots de Lao Zhao, une explosion de bruit grammatical frappe le visage.

Étant donné que l'opération est très proche de la couche inférieure, il est difficile de trouver une bonne méthode d'optimisation du code au niveau macro. Si les conditions de filtrage, c'est-à-dire la logique métier, sont plus compliquées, le code sera complètement différent, et l'intelligibilité et la maintenabilité seront comme un miroir.

Comparons maintenant les performances temporelles :

XmlDocment    26ms    
XPathNavigator    26ms    
XmlTextReader    20ms    
Xml Linq    28ms

Les données des quatre méthodes sont devenues proches, la consommation de temps de Document et Navigator a considérablement diminué et la méthode Reader n'a pas baissé beaucoup, car il faut encore le lire depuis le début. En fin de compte, la réduction de 3 ms peut être attribuée à la réduction de la surcharge de création d'objet d'entité. Ce qui est plus étrange, c'est que la méthode Linq n'a pas changé et est finalement tombée.

Vous pouvez tester différentes conditions de requête. On constate que chacune de ces quatre méthodes a sa propre limite de performances, qui est liée à la taille de la source XML. Par exemple, pour les deux premières méthodes, cela dépend du temps d'exécution de la méthode XmlDocument.Load. Sur ma machine, il faut 23 ms pour charger le Xml. La méthode Linq n'est pas incassable S'il y a peu de résultats à traiter, le temps d'exécution sera réduit de 1 à 2 millisecondes.

En mode Document et Navigateur, les performances diminueront considérablement à mesure que la quantité de données augmente. Il est facile de deviner que c'est parce qu'ils créent beaucoup d'objets inutiles. En regardant l'utilisation de la mémoire de chaque méthode, nous pouvons voir que lorsque toutes les données sont chargées sans filtrage, la méthode Document occupe environ 23,3 Mo de mémoire, tandis que la méthode Navigator n'en occupe qu'environ 22,9 Mo. Cela explique également pourquoi les performances. de la méthode Document diminue de manière plus évidente. Le mode Lecteur est entièrement chargé de données et ne nécessite qu'environ 20,1 Mo de mémoire, sans compter la surcharge liée au démarrage du programme lui-même, il occupe moins de la moitié de la mémoire par rapport aux deux méthodes précédentes. La méthode Linq a une autre performance étonnante en termes de mémoire, représentant moins de 500 Ko de plus que la méthode Reader.

Une analyse plus approfondie a conduit à une conclusion supplémentaire : sauf en cas de besoin particulier, utilisez XmlTextReader avec prudence. Il est mal préparé aux changements et sujet aux erreurs. Il est plus fortement recommandé d'utiliser la méthode Linq. Bien que les performances temporelles soient légèrement inférieures à celles de la méthode Navigator dans certains cas, ses excellentes performances d'utilisation de la mémoire ont établi son premier choix. Et je crois que Linq To XML sera encore plus puissant à l'avenir.

Ce qui précède est la comparaison des performances des méthodes de lecture de données XML (2). Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn