加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在ruby中创建大文件xml

发布时间:2020-12-16 19:35:50 所属栏目:百科 来源:网络整理
导读:我想把一些数据写入 XML文件( XML文件会到?50 MB). 我发现nokogiri(1.5.0)宝石是最有效的解析(只读和不写). Nokogiri不是写入XML文件的好选择,因为它在内存中保存完整的XML数据,直到写入最后写入它. 我发现builder(3.0.0)是一个很好的选择,但不知道它是否是
我想把一些数据写入 XML文件( XML文件会到?50 MB).

我发现nokogiri(1.5.0)宝石是最有效的解析(只读和不写). Nokogiri不是写入XML文件的好选择,因为它在内存中保存完整的XML数据,直到写入最后写入它.

我发现builder(3.0.0)是一个很好的选择,但不知道它是否是最佳选择.

我使用以下简单代码尝试了一些基准测试:

(1..500000).each do |k|
    xml.products {
      xml.widget {
        xml.id_ k
        xml.name "Awesome widget"
      }
    }
    end

Nokogiri需要大约143秒钟,内存消耗逐渐增加,最终达到约700 MB.

Builder耗时约123秒,内存消耗稳定在10 MB.

那么在Ruby中编写巨大的XML文件(50 MB)有更好的解决方案?

Nokogiri文件:

require 'rubygems'
require 'nokogiri'
a = Time.now
builder = Nokogiri::XML::Builder.new do |xml|
  xml.root {
    (1..500000).each do |k|
    xml.products {
      xml.widget {
        xml.id_ k
        xml.name "Awesome widget"
      }
    }
    end
  }
end
o = File.new("test_noko.xml","w")
o.write(builder.to_xml)
o.close
puts (Time.now-a).to_s

生成器文件:

require 'rubygems'
require 'builder'
a = Time.now
File.open("test.xml",'w') {|f|
xml = Builder::XmlMarkup.new(:target => f,:indent => 1)

  (1..500000).each do |k|
    xml.products {
      xml.widget {
        xml.id_ k
        xml.name "Awesome widget"
      }
    }
    end

}
puts (Time.now-a).to_s

解决方法

解决方案1

如果速度是您的主要关注点,我只需直接使用libxml-ruby(http://libxml.rubyforge.org/rdoc/):

$time ruby test.rb 

real    0m7.352s
user    0m5.867s
sys     0m0.921s

api很直接

require 'rubygems'
require 'xml'
doc = XML::Document.new()
doc.root = XML::Node.new('root_node')
root = doc.root

500000.times do |k|
  root << elem1 = XML::Node.new('products')
  elem1 << elem2 = XML::Node.new('widget')
  elem2['id'] = k.to_s
  elem2['name'] = 'Awesome widget'
end

doc.save('foo.xml',:indent => false,:encoding => XML::Encoding::UTF_8)

使用:indent =>在这种情况下,true并没有太多的区别,但是对于更复杂的xml文件,它可能会做.

$time ruby?? test.rb#(带缩进)

real    0m7.395s
user    0m6.050s
sys     0m0.847s

解决方案2

当然最快的解决方案,而不是建立在内存上只是为了手动编写xml,但是很容易产生错误的其他来源,例如可能是无效的xml.

$time ruby test.rb 

real    0m1.131s
user    0m0.873s
sys     0m0.126s

这里是代码:

f = File.open("foo.xml","w")
f.puts('<doc>')
500000.times do |k|
  f.puts "<product><widget id="#{k}" name="Awesome widget" /></product>"
end
f.puts('</doc>')
f.close

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读