为什么使用 ruby 查找具有所需文本的节点比使用 xpath 更快?
Why finding node with desired text is faster with ruby than with xpath?
最近我不得不检查 html 个节点是否包含所需的文本。令我惊讶的是,当我重构代码以使用 xpath 选择器时,它变得慢了 10 倍。有原始代码的简化版本与基准测试
# has_keyword_benchmark.rb
require 'benchmark'
require 'nokogiri'
Doc = Nokogiri("
<div>
<div>
A
</div>
<p>
<b>A</b>
</p>
<span>
B
</span>
</div>")
def has_keywords_with_xpath
Doc.xpath('./*[contains(., "A")]').size > 0
end
def has_keywords_with_ruby
Doc.text.include? 'A'
end
iterations = 10_000
Benchmark.bm(27) do |bm|
bm.report('checking if has keywords with xpath') do
iterations.times do
has_keywords_with_xpath
end
end
bm.report('checking if has keywords with ruby') do
iterations.times do
has_keywords_with_ruby
end
end
end
当我 运行 ruby has_keyword_benchmark.rb
我得到
user system total real
checking if has keywords with xpath 0.400000 0.020000 0.420000 ( 0.428484)
checking if has keywords with ruby 0.020000 0.000000 0.020000 ( 0.023773)
直观地检查节点是否有一些文本应该使用 xpath 更快,但事实并非如此。有人知道为什么吗?
通常,XPath 表达式的解析和编译比实际执行它所花的时间要长得多,即使是在相当大的文档上也是如此。例如,对于 Saxon,运行 表达式 count(//*[contains(., 'e')])
针对 1Mb 源文档,编译路径表达式需要 200 毫秒,而执行它大约需要 18 毫秒。
如果您的 XPath API 允许您编译一次 XPath 表达式然后重复执行它(或者如果它在幕后缓存已编译的表达式)那么绝对值得利用该功能。
实际的 XPath 执行可能至少与您手写的导航代码一样快,甚至可能更快。导致开销的是准备工作。
最近我不得不检查 html 个节点是否包含所需的文本。令我惊讶的是,当我重构代码以使用 xpath 选择器时,它变得慢了 10 倍。有原始代码的简化版本与基准测试
# has_keyword_benchmark.rb
require 'benchmark'
require 'nokogiri'
Doc = Nokogiri("
<div>
<div>
A
</div>
<p>
<b>A</b>
</p>
<span>
B
</span>
</div>")
def has_keywords_with_xpath
Doc.xpath('./*[contains(., "A")]').size > 0
end
def has_keywords_with_ruby
Doc.text.include? 'A'
end
iterations = 10_000
Benchmark.bm(27) do |bm|
bm.report('checking if has keywords with xpath') do
iterations.times do
has_keywords_with_xpath
end
end
bm.report('checking if has keywords with ruby') do
iterations.times do
has_keywords_with_ruby
end
end
end
当我 运行 ruby has_keyword_benchmark.rb
我得到
user system total real
checking if has keywords with xpath 0.400000 0.020000 0.420000 ( 0.428484)
checking if has keywords with ruby 0.020000 0.000000 0.020000 ( 0.023773)
直观地检查节点是否有一些文本应该使用 xpath 更快,但事实并非如此。有人知道为什么吗?
通常,XPath 表达式的解析和编译比实际执行它所花的时间要长得多,即使是在相当大的文档上也是如此。例如,对于 Saxon,运行 表达式 count(//*[contains(., 'e')])
针对 1Mb 源文档,编译路径表达式需要 200 毫秒,而执行它大约需要 18 毫秒。
如果您的 XPath API 允许您编译一次 XPath 表达式然后重复执行它(或者如果它在幕后缓存已编译的表达式)那么绝对值得利用该功能。
实际的 XPath 执行可能至少与您手写的导航代码一样快,甚至可能更快。导致开销的是准备工作。