gpt4 book ai didi

ruby - Nokogiri 构建器在大型 XML 上的性能?

转载 作者:数据小太阳 更新时间:2023-10-29 08:52:20 25 4
gpt4 key购买 nike

我需要构建一个巨大的 XML 文件,大约 1-50 MB。我认为使用构建器就足够有效了,而且在某种程度上是这样。问题是,程序执行到最后一行后并没有立即结束,但 Ruby 还在做几秒钟的事情,也许是垃圾收集?之后程序终于结束了。

举一个真实的例子,我测量了构建一个XML文件的时间。它在构建 XML 时输出 55​​ 秒(后面有一个数据库,所以需要很长时间),但 Ruby 仍然处理了大约 15 秒,处理器快要发疯了。

伪/真代码如下:

...
builder = Nokogiri::XML::Builder.with(doc) do |xml|
build_node(xml)
end
...

def build_node(xml)
...
xml["#{namespace}"] if namespace
xml.send("#{elem_name}", attrs_hash) do |elem_xml|
...
if has_children
if type
case type
when XML::TextContent::PLAIN
elem_xml.text text_content
when XML::TextContent::COMMENT
elem_xml.comment text_content
when XML::TextContent::CDATA
elem_xml.cdata text_content
end
else
build_node(elem_xml)
end
end
end
end

请注意,我使用自己的类结构使用不同的方法,构建速度是相同的,但在最后一行程序正常结束,但现在我被迫使用 Nokogiri,所以我必须找到解决方案。

在构建 XML 后,我可以做些什么来避免 X 秒长的开销?有可能吗?

更新:

感谢 Adiel Mittmann 的建议,在创建我的最小工作示例期间,我能够找到问题所在。我现在有一个小的(当然不是那么小的)例子来说明这个问题。

以下代码导致了问题:

xml.send("#{elem_name}_") do |elem_xml|
...
elem_xml.text text_content #This line is the problem
...
end

因此该行根据Nokogiri的文档执行了以下代码:

def create_text_node string, &block
Nokogiri::XML::Text.new string.to_s, self, &block
end

Text node creation code然后被执行。那么,这里到底发生了什么?

更新 2:

经过一些其他尝试后,问题可以通过以下方式轻松重现:

builder = Nokogiri::XML::Builder.new do |xml|
0.upto(81900) do
xml.text "test"
end
end
puts "End"

那么它真的是 Nokogiri 本身吗?我有什么选择吗?

最佳答案

你的例子在这里也需要很长时间才能执行。你是对的:是垃圾收集器执行了这么长时间。试试这个:

require 'nokogiri'
class A
def a
builder = Nokogiri::XML::Builder.new do |xml|
0.upto(81900) do
xml.text "test"
end
end
end
end
A.new.a
puts "End1"
GC.start
puts "End2"

此处,延迟发生在"End1""End2" 之间。打印"End2"后,程序立即关闭。

请注意,我创建了一个对象来演示它。否则,构建器生成的数据只能在程序结束时被垃圾回收。

至于完成您想要完成的事情的最佳方式,我建议您问另一个问题,详细说明您究竟想用 XML 文件做什么。

关于ruby - Nokogiri 构建器在大型 XML 上的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9731089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com