Improved perf of XPath::Evaluator#node_matches?

Using the benchmark xpath/evaluator/node_matches_bench.rb the results
prior to this commit were as following for 3 cases:

    name only:          737633 i/s
    namespace wildcard: 612196 i/s
    name wildcard:      516030 i/s

With this commit said numbers have changed to the following:

    name only:          746086  i/s
    namespace wildcard: 1097168 i/s
    name wildcard:      1151255 i/s

This results in the following increase of performance for each case:

    name only:          1,011x (insignificant)
    namespace wildcard: 1,79x
    name wildcard:      2,23x

In the benchmark xpath/evaluator/big_xml_average_bench.rb the difference
isn't really noticable as said benchmark only queries elements by names,
of which the performance hasn't really improved.
This commit is contained in:
Yorick Peterse 2015-05-07 00:05:25 +02:00
parent 361374c813
commit b5e63dc50e
1 changed files with 8 additions and 5 deletions

View File

@ -59,6 +59,9 @@ module Oga
# evaluator.evaluate('$number') # => 10
#
class Evaluator
# Wildcard for node names/namespace prefixes.
STAR = '*'
##
# @param [Oga::XML::Document|Oga::XML::Node] document
# @param [Hash] variables Hash containing variables to expose to the XPath
@ -534,7 +537,7 @@ module Oga
next unless context_node.respond_to?(:available_namespaces)
context_node.available_namespaces.each do |_, namespace|
if namespace.name == name or name == '*'
if namespace.name == name or name == STAR
nodes << namespace
end
end
@ -1643,8 +1646,8 @@ module Oga
# If only the name is given and is a wildcard then we'll also want to
# match the namespace as a wildcard.
if !ns and name == '*'
ns = '*'
if !ns and name == STAR
ns = STAR
end
name_matches = name_matches?(xml_node, name)
@ -1686,7 +1689,7 @@ module Oga
def name_matches?(xml_node, name)
return false unless xml_node.respond_to?(:name)
return xml_node.name == name || name == '*'
return name == STAR ? true : xml_node.name == name
end
##
@ -1699,7 +1702,7 @@ module Oga
def namespace_matches?(xml_node, ns)
return false unless xml_node.respond_to?(:namespace)
return xml_node.namespace.to_s == ns || ns == '*'
return ns == STAR ? true : xml_node.namespace.to_s == ns
end
##