Je sais qu'il y a des dizaines de façons de sélectionner le premier élément enfant de Nokogiri, mais lequel est le moins cher? Je ne peux pas me déplacer en utilisant Node # children, ce qui semble terriblement cher. Dites qu'il y a 10000 nœuds enfants, et je ne veux pas toucher les 9999 autres ...Quel est le moyen le moins cher de sélectionner un nœud enfant dans Nokogiri?
Répondre
Cependant, si le nœud que vous recherchez n'est PAS le premier (par exemple, le 99ème), alors il n'y a pas de moyen plus rapide de sélectionner ce nœud que d'y appeler #children et index.
Vous avez raison de dire qu'il est coûteux de construire un NodeSet pour tous les enfants si vous ne voulez que le premier.
Un facteur limitatif est que libxml2 (la bibliothèque XML sous-jacente à Nokogiri) stocke les enfants d'un nœud sous la forme d'une liste chaînée. Vous devrez donc parcourir la liste (O (n)) pour sélectionner le nœud enfant souhaité.
Il serait possible d'écrire une méthode pour retourner simplement le nième enfant, sans instancier un objet NodeSet ou même ruby pour tous les autres enfants. Mon conseil serait d'ouvrir une demande de fonctionnalité, au http://github.com/tenderlove/nokogiri/issues ou envoyer un courriel à la liste de diffusion nokogiri.
Vous pouvez essayer vous-même et comparer le résultat.
J'ai créé une référence rapide: http://gist.github.com/283825
$ ruby test.rb
Rehearsal ---------------------------------------------------
xpath/first() 3.290000 0.030000 3.320000 ( 3.321197)
xpath.first 3.360000 0.010000 3.370000 ( 3.381171)
at 4.540000 0.020000 4.560000 ( 4.564249)
at_xpath 3.420000 0.010000 3.430000 ( 3.430933)
children.second 0.220000 0.010000 0.230000 ( 0.233090)
----------------------------------------- total: 14.910000sec
user system total real
xpath/first() 3.280000 0.000000 3.280000 ( 3.288647)
xpath.first 3.350000 0.020000 3.370000 ( 3.374778)
at 4.530000 0.040000 4.570000 ( 4.580512)
at_xpath 3.410000 0.010000 3.420000 ( 3.421551)
children.second 0.220000 0.010000 0.230000 ( 0.226846)
De mes tests, children
semble être la méthode la plus rapide.
Les quatre premières approches que vous avez utilisées utilisent xpath, qui est très lent. L'approche enfants, comme mentionné dans la question, analyse le nœud parent entier, ce qui est également inacceptable. Essayez-les avec 100 fois plus de nœuds et 1/100 de tests. – Steinbitglis
Merci de m'avoir montré la bibliothèque de référence en passant ... Je pense que cela pourrait être très utile dans le futur :-) – Steinbitglis
Une approche qui n'utilise XPath ni des résultats dans l'analyse du parent tout est d'utiliser les deux enfants # Node(), Noeud # next_sibling() et l'élément Node #?()
Quelque chose comme ça ...
Nœud # enfant est le moyen le plus rapide d'obtenir le premier élément enfant.def first(node)
element = node.child
while element
if element.element?
return element
else
element = element.next
end
end
nil
end
Cela a été fait! Merci :-) http://github.com/tenderlove/nokogiri/issues#issue/211 – Steinbitglis