From b5e63dc50eb8423a1839fbfb815521e8f3a1e378 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 7 May 2015 00:05:25 +0200 Subject: [PATCH] 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. --- lib/oga/xpath/evaluator.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 2ba45ba..8892318 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -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 ##