Nokogiri构建器在巨大的XML上表现?

我需要构建一个大约1-50 MB的巨大XML文件。 我认为使用构建器会足够有效,而且有点。 问题是,在程序到达最后一行后它不会立即结束,但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的建议,在创建我的最小工作示例期间,我能够找到问题所在。 我现在有一个小的(好不是那么小)的例子来certificate这个问题。

以下代码导致问题:

 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 

然后执行文本节点创建代码 。 那么,到底发生了什么?

更新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内置(sic)Builder。 我也用它来生成大型XML文件,而且它的占用空间很小。