Nokogiri에서 첫 번째 자식 요소를 선택하는 데 수십 가지 방법이 있지만 가장 저렴한 방법은 무엇입니까? Node # children을 사용하여 돌아갈 수 없습니다. 10000 개의 자식 노드가 있다고 가정하고 9999 명의 다른 노드를 만지 싶지는 않습니다 ...Nokogiri에서 하위 노드를 선택하는 절대적으로 가장 저렴한 방법은 무엇입니까?
답변
노드 # 하위는 첫 번째 하위 요소를 가져 오는 가장 빠른 방법입니다.
그러나 찾는 노드가 첫 번째가 아닌 경우 (예 : 99 번째) #children 및 색인을 호출하는 것보다 노드를 선택하는 더 빠른 방법이 없습니다.
첫 번째 노드 만 원한다면 모든 노드에 대해 NodeSet을 작성하는 것이 좋습니다.
하나의 제한 요소는 libxml2 (Nokogiri의 기본 XML 라이브러리)가 노드의 하위를 연결된 목록으로 저장한다는 것입니다. 따라서 원하는 하위 노드를 선택하려면 목록 (O (n))을 탐색해야합니다.
노드 집합을 인스턴스화하지 않고 n 번째 자식을 반환하는 메서드를 작성하거나 다른 모든 자식에 대해 루비 개체를 만들 수도 있습니다. 내 조언은 기능 요청을 열어 http://github.com/tenderlove/nokogiri/issues으로 보내거나 nokogiri 메일 링리스트로 이메일을 보내는 것입니다.
직접 시도하고 결과를 벤치 마크 할 수 있습니다. 내 테스트에서 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)
이 children
가장 빠른 방법으로 나타납니다
네 가지 첫 번째 접근 방식은 xpath를 사용하며 매우 느립니다. 질문에서 언급 한 것처럼 아이들이 접근하는 것은 부모 노드 전체를 구문 분석합니다. 이는 또한 받아 들일 수없는 것입니다. 노드 수를 100 배로하고 테스트 수를 1/100로 사용해보십시오. – Steinbitglis
그런데 벤치 마크 라이브러리를 보여 주셔서 고마워요. 나는 미래에 유용 할 수 있다고 생각합니다 :-) – Steinbitglis
둘 다 전체 부모를 구문 분석 XPath를하거나 결과를 사용 없다는 것을 접근 방법은 두 노드 # 아이(), 노드 번호의 next_sibling()와 노드 번호 요소를 사용할 수 있나요?()이 같은
뭔가 ...
def first(node)
element = node.child
while element
if element.element?
return element
else
element = element.next
end
end
nil
end
끝났습니다! 감사 :-) http://github.com/tenderlove/nokogiri/issues#issue/211 – Steinbitglis